rpms/kernel-xen/devel Makefile.config, NONE, 1.1.2.1 genkey, NONE, 1.1.2.1 linux-2.6-NFSD-badness.patch, NONE, 1.1.2.1 linux-2.6-NFSD-cache_change_attribute-init.patch, NONE, 1.1.2.1 linux-2.6-NFSD-ctlbits.patch, NONE, 1.1.2.1 linux-2.6-NFSD-non-null-getxattr.patch, NONE, 1.1.2.1 linux-2.6-acpi-thinkpad-c2c3.patch, NONE, 1.1.2.1 linux-2.6-atkbd-dell-multimedia.patch, NONE, 1.1.2.1 linux-2.6-autofs-pathlookup.patch, NONE, 1.1.2.1 linux-2.6-build-reference-discarded-opd.patch, NONE, 1.1.2.1 linux-2.6-build-userspace-headers-warning.patch, NONE, 1.1.2.1 linux-2.6-bzimage.patch, NONE, 1.1.2.1 linux-2.6-crash-driver.patch, NONE, 1.1.2.1 linux-2.6-crash-xen.patch, NONE, 1.1.2.1 linux-2.6-crashdump-common.patch, NONE, 1.1.2.1 linux-2.6-crashdump-reboot-exports.patch, NONE, 1.1.2.1 linux-2.6-debug-Wundef.patch, NONE, 1.1.2.1 linux-2.6-debug-disable-builtins.patch, NONE, 1.1.2.1 linux-2.6-debug-dual-line-backtrace.patch, NONE, 1.1.2.1 linux-2.6-debug-list_head.patch, NONE, 1.1.2.1 linux-2.6-debug-no-quiet.patch, NO! NE, 1.1.2.1 linux-2.6-debug-panic-stackdump.patch, NONE, 1.1.2.1 linux-2.6-debug-reference-discarded-return-result.patch, NONE, 1.1.2.1 linux-2.6-debug-singlebiterror.patch, NONE, 1.1.2.1 linux-2.6-debug-slab-backtrace.patch, NONE, 1.1.2.1 linux-2.6-debug-sleep-in-irq-warning.patch, NONE, 1.1.2.1 linux-2.6-debug-spinlock-panic.patch, NONE, 1.1.2.1 linux-2.6-debug-spinlock-taint.patch, NONE, 1.1.2.1 linux-2.6-debug-sysfs-crash-debugging.patch, NONE, 1.1.2.1 linux-2.6-debug-taint-check.patch, NONE, 1.1.2.1 linux-2.6-debug-taint-proprietary-helpers.patch, NONE, 1.1.2.1 linux-2.6-debug-taint-vm.patch, NONE, 1.1.2.1 linux-2.6-default-clocksource-tsc.patch, NONE, 1.1.2.1 linux-2.6-devmem-xen.patch, NONE, 1.1.2.1 linux-2.6-devmem.patch, NONE, 1.1.2.1 linux-2.6-diskdump.patch, NONE, 1.1.2.1 linux-2.6-dump_smp_call_function.patch, NONE, 1.1.2.1 linux-2.6-execshield-vdso.patch, NONE, 1.1.2.1 linux-2.6-execshield-xen.patch, NONE, 1.1.2.1 linux-2.6-execshield.patch, NONE, 1.1.2.1 linux-2.6-firmware-loader-timeout.patch, NONE! ,1.1.2.1 linux-2.6-ide-tune-locking.patch,NONE,1.1.2.1 linux-2! .6-input

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Fri Dec 2 22:11:34 UTC 2005


Author: sct

Update of /cvs/dist/rpms/kernel-xen/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv26986

Modified Files:
      Tag: private-kernel-xen-2_6_12-1_13_FC5-sct-branch
	.cvsignore Makefile kernel-xen.spec 
	linux-2.6-build-nonintconfig.patch sources 
Added Files:
      Tag: private-kernel-xen-2_6_12-1_13_FC5-sct-branch
	Makefile.config genkey linux-2.6-NFSD-badness.patch 
	linux-2.6-NFSD-cache_change_attribute-init.patch 
	linux-2.6-NFSD-ctlbits.patch 
	linux-2.6-NFSD-non-null-getxattr.patch 
	linux-2.6-acpi-thinkpad-c2c3.patch 
	linux-2.6-atkbd-dell-multimedia.patch 
	linux-2.6-autofs-pathlookup.patch 
	linux-2.6-build-reference-discarded-opd.patch 
	linux-2.6-build-userspace-headers-warning.patch 
	linux-2.6-bzimage.patch linux-2.6-crash-driver.patch 
	linux-2.6-crash-xen.patch linux-2.6-crashdump-common.patch 
	linux-2.6-crashdump-reboot-exports.patch 
	linux-2.6-debug-Wundef.patch 
	linux-2.6-debug-disable-builtins.patch 
	linux-2.6-debug-dual-line-backtrace.patch 
	linux-2.6-debug-list_head.patch linux-2.6-debug-no-quiet.patch 
	linux-2.6-debug-panic-stackdump.patch 
	linux-2.6-debug-reference-discarded-return-result.patch 
	linux-2.6-debug-singlebiterror.patch 
	linux-2.6-debug-slab-backtrace.patch 
	linux-2.6-debug-sleep-in-irq-warning.patch 
	linux-2.6-debug-spinlock-panic.patch 
	linux-2.6-debug-spinlock-taint.patch 
	linux-2.6-debug-sysfs-crash-debugging.patch 
	linux-2.6-debug-taint-check.patch 
	linux-2.6-debug-taint-proprietary-helpers.patch 
	linux-2.6-debug-taint-vm.patch 
	linux-2.6-default-clocksource-tsc.patch 
	linux-2.6-devmem-xen.patch linux-2.6-devmem.patch 
	linux-2.6-diskdump.patch 
	linux-2.6-dump_smp_call_function.patch 
	linux-2.6-execshield-vdso.patch linux-2.6-execshield-xen.patch 
	linux-2.6-execshield.patch 
	linux-2.6-firmware-loader-timeout.patch 
	linux-2.6-ide-tune-locking.patch 
	linux-2.6-input-kill-stupid-messages.patch 
	linux-2.6-input-usblegacy.patch 
	linux-2.6-kdump-needs-not-embedded.patch 
	linux-2.6-max-symlinks.patch linux-2.6-missing-exports.patch 
	linux-2.6-modsign-core.patch linux-2.6-modsign-crypto.patch 
	linux-2.6-modsign-include.patch linux-2.6-modsign-ksign.patch 
	linux-2.6-modsign-mpilib.patch linux-2.6-modsign-script.patch 
	linux-2.6-module_version.patch 
	linux-2.6-net-sundance-ip100A.patch linux-2.6-netconsole.patch 
	linux-2.6-netdump.patch 
	linux-2.6-obsolete-idescsi-warning.patch 
	linux-2.6-obsolete-oss-warning.patch 
	linux-2.6-optimise-for-size.patch 
	linux-2.6-proc-vmcore-needs-not-embedded.patch 
	linux-2.6-procfs-i_nlink-miscalculate.patch 
	linux-2.6-radeon-backlight.patch 
	linux-2.6-sata-enable-atapi-by-default.patch 
	linux-2.6-scsi-advansys-enabler.patch 
	linux-2.6-scsi-advansys-pcitable.patch 
	linux-2.6-scsi-megaraid-legacy.patch 
	linux-2.6-selinux-hush.patch linux-2.6-serial-of.patch 
	linux-2.6-serial-tickle-nmi.patch linux-2.6-sleepon.patch 
	linux-2.6-sound-emu10k1-ac97.patch linux-2.6-squashfs.patch 
	linux-2.6-swsusp-nofreeze.patch 
	linux-2.6-time-isr-ratelimit.patch linux-2.6-tux.patch 
	linux-2.6-ub.patch linux-2.6-unexport-symbols.patch 
	linux-2.6-valid-ether-addr.patch linux-2.6-vdso-xen.patch 
	linux-2.6-vm-oomkiller-debugging.patch 
	linux-2.6-vm-silence-atomic-alloc-failures.patch 
	linux-2.6-write-protect-rodata.patch 
	linux-2.6-x86-apic-off-by-default.patch 
	linux-2.6-x86-tune-p4.patch linux-2.6-x86-vga-vidfail.patch 
	linux-2.6-xen-additional.patch linux-2.6-xen-compile.patch 
	linux-2.6-xen-kprobes.patch linux-2.6-xen-merge.patch 
	linux-2.6-xen-no-tls-warn.patch linux-2.6-xen-vdso-note.patch 
	linux-2.6.14-intel-cache-build.patch 
	linux-2.6.14-kauditd-suspend.patch linux-2.6.14.tar.bz2.sign 
	linux-2.6.15-cell-bogus-console-fix.patch 
	linux-2.6.15-default-powerpc.patch 
	linux-2.6.15-mv643xx-fixes.patch 
	linux-2.6.15-ppc-cell-basics.patch 
	linux-2.6.15-rc1-ppc-vdso-2.patch 
	linux-2.6.15-rc1-ppc64-syscallpath.patch mirrors 
	patch-2.6.15-rc4-git1.bz2.sign patch-2.6.15-rc4.bz2.sign 
	upstream upstream-key.gpg 
Log Message:
Initial merge of current linux-2.6-merge.hg tree into rawhide


***** Error reading new file: [Errno 2] No such file or directory: 'Makefile.config'

--- NEW FILE genkey ---
%pubring kernel.pub
%secring kernel.sec
Key-Type: DSA
Key-Length: 512
Name-Real: Red Hat, Inc.
Name-Comment: Kernel Module GPG key
%commit

linux-2.6-NFSD-badness.patch:
 svc.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-NFSD-badness.patch ---
 
--- linux-2.6.14/fs/lockd/svc.c~	2005-11-22 10:37:03.000000000 -0500
+++ linux-2.6.14/fs/lockd/svc.c	2005-11-22 10:37:38.000000000 -0500
@@ -305,7 +305,7 @@ lockd_down(void)
 	 * the lockd semaphore, we can't wait around forever ...
 	 */
 	clear_thread_flag(TIF_SIGPENDING);
-	interruptible_sleep_on_timeout(&lockd_exit, HZ);
+	wait_event_timeout(lockd_exit, nlmsvc_pid == 0, HZ);
 	if (nlmsvc_pid) {
 		printk(KERN_WARNING 
 			"lockd_down: lockd failed to exit, clearing pid\n");

linux-2.6-NFSD-cache_change_attribute-init.patch:
 inode.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6-NFSD-cache_change_attribute-init.patch ---
Make sure cache_change_attribute is initialized to jiffies
so when the mtime changes on directory, the directory
will be refreshed.

Signed-off by: Steve Dickson <steved at redhat.com>
---------------------------------------------
--- linux-2.6.14/fs/nfs/inode.c.orig	2005-11-29 20:53:57.000000000 -0500
+++ linux-2.6.14/fs/nfs/inode.c	2005-11-30 08:55:14.000000000 -0500
@@ -2066,6 +2066,7 @@ static struct inode *nfs_alloc_inode(str
 		return NULL;
 	nfsi->flags = 0UL;
 	nfsi->cache_validity = 0UL;
+	nfsi->cache_change_attribute = jiffies;
 #ifdef CONFIG_NFS_V3_ACL
 	nfsi->acl_access = ERR_PTR(-EAGAIN);
 	nfsi->acl_default = ERR_PTR(-EAGAIN);

linux-2.6-NFSD-ctlbits.patch:
 fs/nfsd/nfs4state.c          |    3 ++
 fs/nfsd/nfsctl.c             |   59 +++++++++++++++++++++++++++++++++++++++++++
 fs/nfsd/nfssvc.c             |   10 +++++--
 include/linux/nfsd/syscall.h |   14 ++++++++--
 4 files changed, 82 insertions(+), 4 deletions(-)

--- NEW FILE linux-2.6-NFSD-ctlbits.patch ---
--- linux-2.6.14/fs/nfsd/nfsctl.c.aa1	2005-11-08 09:31:44.000000000 +0000
+++ linux-2.6.14/fs/nfsd/nfsctl.c	2005-11-08 09:32:14.000000000 +0000
@@ -36,7 +36,9 @@
 
 #include <asm/uaccess.h>
 
+int nfsd_port = 2049;
+unsigned int nfsd_portbits = 0;
 unsigned int nfsd_versbits = ~0;
 
 /*
  *	We have a single directory with 9 nodes in it.
@@ -53,6 +55,7 @@ enum {
 	NFSD_Fh,
 	NFSD_Threads,
 	NFSD_Versions,
+	NFSD_Ports,
 	/*
 	 * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
 	 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
@@ -76,6 +73,7 @@ static ssize_t write_getfd(struct file *
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
 static ssize_t write_threads(struct file *file, char *buf, size_t size);
 static ssize_t write_versions(struct file *file, char *buf, size_t size);
+static ssize_t write_ports(struct file *file, char *buf, size_t size);
 #ifdef CONFIG_NFSD_V4
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
@@ -92,7 +88,8 @@ static ssize_t (*write_op[])(struct file
 	[NFSD_Getfs] = write_getfs,
 	[NFSD_Fh] = write_filehandle,
 	[NFSD_Threads] = write_threads,
 	[NFSD_Versions] = write_versions,
+	[NFSD_Ports] = write_ports,
 #ifdef CONFIG_NFSD_V4
 	[NFSD_Leasetime] = write_leasetime,
 	[NFSD_RecoveryDir] = write_recoverydir,
@@ -358,7 +351,60 @@ static ssize_t write_threads(struct file
 	sprintf(buf, "%d\n", nfsd_nrthreads());
 	return strlen(buf);
 }
+static ssize_t write_ports(struct file *file, char *buf, size_t size)
+{
+	/*
+	 * Format:
+	 *   family proto proto address port
+	 */
+	char *mesg = buf;
+	char *family, *udp, *tcp, *addr; 
+	int len, port = 0;
+	ssize_t tlen = 0;
+
+	if (buf[size-1] != '\n')
+		return -EINVAL;
+	buf[size-1] = 0;
 
+	family = mesg;
+	len = qword_get(&mesg, family, size);
+	if (len <= 0) return -EINVAL;
+
+	tlen += len;
+	udp = family+len+1;
+	len = qword_get(&mesg, udp, size);
+	if (len <= 0) return -EINVAL;
+
+	tlen += len;
+	tcp = udp+len+1;
+	len = qword_get(&mesg, tcp, size);
+	if (len <= 0) return -EINVAL;
+
+	tlen += len;
+	addr = tcp+len+1;
+	len = qword_get(&mesg, addr, size);
+	if (len <= 0) return -EINVAL;
+
+	len = get_int(&mesg, &port);
+	if (len)
+		return len;
+
+	tlen += sizeof(port);
+	if (port)
+		nfsd_port = port;
+
+	if (strcmp(tcp, "tcp") == 0 || strcmp(tcp, "TCP") == 0)
+		NFSCTL_TCPSET(nfsd_portbits);
+	else
+		NFSCTL_TCPUNSET(nfsd_portbits);
+
+	if (strcmp(udp, "udp") == 0 || strcmp(udp, "UDP") == 0)
+		NFSCTL_UDPSET(nfsd_portbits);
+	else
+		NFSCTL_UDPUNSET(nfsd_portbits);
+
+	return tlen;
+}
 static ssize_t write_versions(struct file *file, char *buf, size_t size)
 {
 	/*
@@ -484,6 +508,7 @@ static int nfsd_fill_super(struct super_
 		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_Ports] = {"ports", &transaction_ops, S_IWUSR|S_IRUSR},
 #ifdef CONFIG_NFSD_V4
 		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
--- linux-2.6.14/fs/nfsd/nfs4state.c.aa1	2005-11-08 09:31:51.000000000 +0000
+++ linux-2.6.14/fs/nfsd/nfs4state.c	2005-11-08 09:32:14.000000000 +0000
@@ -3319,6 +3319,9 @@ __nfs4_state_shutdown(void)
 void
 nfs4_state_shutdown(void)
 {
+	if (!nfs4_init)
+		return;
+
 	nfs4_lock_state();
 	nfs4_release_reclaim();
 	__nfs4_state_shutdown();
--- linux-2.6.14/fs/nfsd/nfssvc.c.aa1	2005-11-08 09:31:44.000000000 +0000
+++ linux-2.6.14/fs/nfsd/nfssvc.c	2005-11-08 09:32:14.000000000 +0000
@@ -64,6 +64,8 @@ struct nfsd_list {
 };
 static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
+
 static struct svc_version *	nfsd_version[] = {
 	[2] = &nfsd_version2,
 #if defined(CONFIG_NFSD_V3)
@@ -110,8 +112,8 @@ nfsd_svc(unsigned short port, int nrserv
 	struct list_head *victim;
 	
 	lock_kernel();
-	dprintk("nfsd: creating service: vers 0x%x\n",
-		nfsd_versbits);
+	dprintk("nfsd: creating service: port %d vers 0x%x proto 0x%x\n",
+		nfsd_port, nfsd_versbits, nfsd_portbits);
 	error = -EINVAL;
 	if (nrservs <= 0)
 		nrservs = 0;
@@ -126,11 +147,15 @@ nfsd_svc(unsigned short port, int nrserv
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
 		if (nfsd_serv == NULL)
 			goto out;
+		if (NFSCTL_UDPISSET(nfsd_portbits))
+			port = nfsd_port;
 		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
 		if (error < 0)
 			goto failure;
 
 #ifdef CONFIG_NFSD_TCP
+		if (NFSCTL_TCPISSET(nfsd_portbits))
+			port = nfsd_port;
 		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
 		if (error < 0)
 			goto failure;
--- linux-2.6.14/include/linux/nfsd/syscall.h.aa1	2005-11-08 09:31:44.000000000 +0000
+++ linux-2.6.14/include/linux/nfsd/syscall.h	2005-11-08 09:32:14.000000000 +0000
@@ -40,19 +40,28 @@
 #define	NFSCTL_GETFS		8	/* get an fh by path with max FH len */
 
 /*
- * Macros used to set version
+ * Macros used to set version and protocol
  */
 #define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |=  (1 << (_v)))
 #define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v)))
 #define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v)))
 
 #if defined(CONFIG_NFSD_V4)
 #define	NFSCTL_VERALL	(0x1c /* 0b011100 */)
 #elif defined(CONFIG_NFSD_V3)
 #define	NFSCTL_VERALL	(0x0c /* 0b001100 */)
 #else
 #define	NFSCTL_VERALL	(0x04 /* 0b000100 */)
 #endif
+
+#define NFSCTL_UDPSET(_cltbits)       ((_cltbits) |=  (1 << (17 - 1)))
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1)))
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1)))
+
+#define NFSCTL_TCPSET(_cltbits)       ((_cltbits) |=  (1 << (18 - 1)))
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1)))
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1)))
+
 
 /* SVC */
 struct nfsctl_svc {
@@ -135,7 +136,8 @@ extern int		exp_delclient(struct nfsctl_
 extern int		exp_export(struct nfsctl_export *nxp);
 extern int		exp_unexport(struct nfsctl_export *nxp);
 
-extern unsigned int nfsd_versbits;
+extern int nfsd_port;
+extern unsigned int nfsd_versbits, nfsd_portbits;
 
 #endif /* __KERNEL__ */
 

linux-2.6-NFSD-non-null-getxattr.patch:
 vfs.c |   10 ++++++++++
 1 files changed, 10 insertions(+)

--- NEW FILE linux-2.6-NFSD-non-null-getxattr.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1102/fs/nfsd/vfs.c linux-1200/fs/nfsd/vfs.c
--- linux-1102/fs/nfsd/vfs.c
+++ linux-1200/fs/nfsd/vfs.c
@@ -461,6 +461,16 @@ _get_posix_acl(struct dentry *dentry, ch
 	if (error)
 		goto out_err;
 
+	error = -EOPNOTSUPP;
+	if (inode->i_op == NULL)
+		goto out_err;
+	if (inode->i_op->getxattr == NULL)
+		goto out_err;
+
+	error = security_inode_getxattr(dentry, key);
+	if (error)
+		goto out_err;
+
 	buflen = inode->i_op->getxattr(dentry, key, NULL, 0);
 	if (buflen <= 0) {
 		error = buflen < 0 ? buflen : -ENODATA;

linux-2.6-acpi-thinkpad-c2c3.patch:
 processor_idle.c |   31 ++++++++++++++++++-------------
 1 files changed, 18 insertions(+), 13 deletions(-)

--- NEW FILE linux-2.6-acpi-thinkpad-c2c3.patch ---
processor_idle.c vs Lindent resulted in something of a trainwreck
with whitespace all over the place.  This diff rearranges teh
processor_power_dmi_table to look like it did before that accident,
and adds two additional BIOS's to the list as encountered by
Fedora users.

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=165590

Signed-off-by: Dave Jones <davej at redhat.com>

--- linux-2.6.13/drivers/acpi/processor_idle.c~	2005-09-09 19:24:25.000000000 -0400
+++ linux-2.6.13/drivers/acpi/processor_idle.c	2005-09-09 19:33:18.000000000 -0400
@@ -94,22 +94,27 @@ static int set_max_cstate(struct dmi_sys
 }
 
 static struct dmi_system_id __initdata processor_power_dmi_table[] = {
-	{set_max_cstate, "IBM ThinkPad R40e", {
-					       DMI_MATCH(DMI_BIOS_VENDOR,
-							 "IBM"),
-					       DMI_MATCH(DMI_BIOS_VERSION,
-							 "1SET60WW")},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	 DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
+	 DMI_MATCH(DMI_BIOS_VERSION, "1SET60WW")},
 	 (void *)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	 DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW")},
+	 (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	 DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") },
+	 (void*)1},
+
 	{set_max_cstate, "Medion 41700", {
-					  DMI_MATCH(DMI_BIOS_VENDOR,
-						    "Phoenix Technologies LTD"),
-					  DMI_MATCH(DMI_BIOS_VERSION,
-						    "R01-A1J")}, (void *)1},
+	 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+	 DMI_MATCH(DMI_BIOS_VERSION, "R01-A1J")},
+	 (void *)1},
+
 	{set_max_cstate, "Clevo 5600D", {
-					 DMI_MATCH(DMI_BIOS_VENDOR,
-						   "Phoenix Technologies LTD"),
-					 DMI_MATCH(DMI_BIOS_VERSION,
-						   "SHE845M0.86C.0013.D.0302131307")},
+	 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+	 DMI_MATCH(DMI_BIOS_VERSION, "SHE845M0.86C.0013.D.0302131307")},
 	 (void *)2},
 	{},
 };

linux-2.6-atkbd-dell-multimedia.patch:
 atkbd.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6-atkbd-dell-multimedia.patch ---

bz 126148

--- linux-2.6.11/drivers/input/keyboard/atkbd.c~	2005-04-16 12:45:00.000000000 -0400
+++ linux-2.6.11/drivers/input/keyboard/atkbd.c	2005-04-16 12:46:28.000000000 -0400
@@ -90,13 +90,13 @@ static unsigned char atkbd_set2_keycode[
 	 82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
 
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
-	173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
+	217,100,255,  0, 97,165,196,  0,156,  0,  0,  0,  0,  0,197,125,
+	173,114,  0,113,  0,  0,198,126,128,  0,  0,140,  0,  0,  0,127,
 	159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
 	157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
 	226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
-	110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
+	110,111,108,112,106,103,195,119,  0,118,109,  0, 99,104,119,  0,
 
 	  0,  0,  0, 65, 99,
 #endif

linux-2.6-autofs-pathlookup.patch:
 expire.c |    4 ++--
 root.c   |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

--- NEW FILE linux-2.6-autofs-pathlookup.patch ---
From: Ian Kent <raven at themaw.net>
To: Jeff Moyer <jmoyer at redhat.com>
cc: autofs at linux.kernel.org, linux-kernel at vger.kernel.org
Subject: Re: autofs4 looks up wrong path element when ghosting is enabled
Date: Sat, 15 Oct 2005 20:30:47 +0800 (WST)

On Mon, 26 Sep 2005, Jeff Moyer wrote:

> ==> Regarding Re: autofs4 looks up wrong path element when ghosting is enabled; Ian Kent <raven at themaw.net> adds:
> 
> raven> On Sat, 24 Sep 2005, Jeff Moyer wrote:
> >> >> >> >> >> Ian, I'm not really sure how we can address this issue
> >> without VFS >> >> changes.  Any ideas?
> >> >> >> 
> >> >> 
> raven> I'm aware of this problem.  I'm not sure how to deal with it yet.
> raven> The case above is probably not that difficult to solve but if the
> raven> last component is a directory it's hard to work out it's a problem.
> >> >> Ugh.  If you're thinking what I think you're thinking, that's an ugly
> >> >> hack.
> >> 
> raven> Don't think so.
> >>
> raven> I've been seeing this for a while. I wasn't quite sure of the source
> raven> but, for some reason your report has cleared that up.
> >>
> raven> The problem is not so much the success returned on the failed mount
> raven> (revalidate). It's the return from the following lookup. This is a
> raven> lookup in a non-root directory. I replaced the non-root lookup with
> raven> the root lookup a while ago and I think this is an unexpected side
> raven> affect of that. Becuase of other changes that lead to that decision
> raven> I think that it should be now be OK to put back the null function
> raven> (always return a negative dentry) that was there before I started
> raven> working on the browable maps feature.
> >>

I've had a look at this a bit more deeply.

As we know we can't make the path walk lookup fail by autofs4_revalidate 
simply returning 0 and to change that in the kernel would be far to 
dangerous. So we need to deal with this during the following lookup. This 
just means we get an unwanted callback to the daemon which will fail 
and should not cause a problem.

I'm still not fully clear on the reasoning behind the logic in 
try_to_fill_dentry when called with a negative dentry. One of the things 
it attempts to do is cache a lookup failure (ENOENT return from the wait). 
Unfortuneatly the subsequent test in autofs4_revalidate is a tautology, 
always returning true. So d_invalidate is never called to cleanup what 
might be a stale dentry. While this is not causing the problem stale 
dentrys are the problem.

I still haven't decided whether it would be a good idea to return 0 
instead of 1 from try_to_fill_dentry for these failed mount attempts. All 
this would do is give the kernel more chances to clean up the stale 
dentries. The dentry in question won't be released at this point as it has 
a non zero reference count (I believe). But sooner or later they will go 
anyway when d_invalidate is called.

So to resolve this we need to ignore negative and unhashed dentries when 
checking if directory dentry is empty.

Please test this patch and let me know how you go.

diff -Nurp linux-2.6.12.orig/fs/autofs4/expire.c linux-2.6.12/fs/autofs4/expire.c
--- linux-2.6.12.orig/fs/autofs4/expire.c	2005-06-18 03:48:29.000000000 +0800
+++ linux-2.6.12/fs/autofs4/expire.c	2005-10-09 15:11:37.000000000 +0800
@@ -177,7 +177,7 @@ resume:
 		DPRINTK("dentry %p %.*s",
 			dentry, (int)dentry->d_name.len, dentry->d_name.name);
 
-		if (!list_empty(&dentry->d_subdirs)) {
+		if (!simple_empty_nolock(dentry)) {
 			this_parent = dentry;
 			goto repeat;
 		}
@@ -269,7 +269,7 @@ static struct dentry *autofs4_expire(str
 			goto next;
 		}
 
-		if ( simple_empty(dentry) )
+		if (simple_empty(dentry))
 			goto next;
 
 		/* Case 2: tree mount, expire iff entire tree is not busy */
diff -Nurp linux-2.6.12.orig/fs/autofs4/root.c linux-2.6.12/fs/autofs4/root.c
--- linux-2.6.12.orig/fs/autofs4/root.c	2005-06-18 03:48:29.000000000 +0800
+++ linux-2.6.12/fs/autofs4/root.c	2005-10-09 15:52:04.000000000 +0800
@@ -386,13 +386,13 @@ static int autofs4_revalidate(struct den
 
 	/* Negative dentry.. invalidate if "old" */
 	if (dentry->d_inode == NULL)
-		return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT);
+		return (dentry->d_time - jiffies <= 0);
 
 	/* Check for a non-mountpoint directory with no contents */
 	spin_lock(&dcache_lock);
 	if (S_ISDIR(dentry->d_inode->i_mode) &&
 	    !d_mountpoint(dentry) && 
-	    list_empty(&dentry->d_subdirs)) {
+	    simple_empty_nolock(dentry)) {
 		DPRINTK("dentry=%p %.*s, emptydir",
 			 dentry, dentry->d_name.len, dentry->d_name.name);
 		spin_unlock(&dcache_lock);


linux-2.6-build-reference-discarded-opd.patch:
 reference_discarded.pl |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6-build-reference-discarded-opd.patch ---
Error: ./fs/quota_v2.o .opd refers to 0000000000000020 R_PPC64_ADDR64    .exit.text

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/scripts/reference_discarded.pl linux-10000/scripts/reference_discarded.pl
--- linux-3022/scripts/reference_discarded.pl
+++ linux-10000/scripts/reference_discarded.pl
@@ -88,6 +88,7 @@ foreach $object (keys(%object)) {
 		    ($from !~ /\.text\.exit$/ &&
 		     $from !~ /\.exit\.text$/ &&
 		     $from !~ /\.data\.exit$/ &&
+		     $from !~ /\.opd$/ &&
 		     $from !~ /\.exit\.data$/ &&
 		     $from !~ /\.altinstructions$/ &&
 		     $from !~ /\.pdr$/ &&

linux-2.6-build-userspace-headers-warning.patch:
 linux-10000/include/linux/config.h    |    4 +++-
 linux-10001/include/linux/config.h    |    2 +-
 linux-2.6.13/arch/powerpc/boot/main.c |    3 +++
 3 files changed, 7 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-build-userspace-headers-warning.patch ---
It's a bad idea to use kernel headers directly.
We have glibc-kernheaders for this purpose.

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/include/linux/config.h linux-10000/include/linux/config.h
--- linux-3022/include/linux/config.h
+++ linux-10000/include/linux/config.h
@@ -2,5 +2,7 @@
 #define _LINUX_CONFIG_H
 
 #include <linux/autoconf.h>
-
+#ifndef __KERNEL__
+#error including kernel header in userspace; use the glibc headers instead!
+#endif
 #endif

In file included from include/asm/cputable.h:18,
                 from include/asm/elf.h:6,
                 from include/linux/elf.h:5,
                 from arch/ppc64/boot/main.c:13:
include/linux/config.h:6:2: error: #error including kernel header in userspace; use the glibc headers instead!
make[1]: *** [arch/ppc64/boot/main.o] Error 1
make[1]: *** Waiting for unfinished jobs....

--- linux-2.6.13/arch/powerpc/boot/main.c~	2005-09-04 16:45:23.000000000 -0400
+++ linux-2.6.13/arch/powerpc/boot/main.c	2005-09-04 16:45:28.000000000 -0400
@@ -8,6 +8,9 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
+
+#define __KERNGLUE__
+
 #include <stdarg.h>
 #include <stddef.h>
 #include "elf.h"
diff -urNp --exclude-from=/home/davej/.exclude linux-10000/include/linux/config.h linux-10001/include/linux/config.h
--- linux-10000/include/linux/config.h
+++ linux-10001/include/linux/config.h
@@ -2,7 +2,7 @@
 #define _LINUX_CONFIG_H
 
 #include <linux/autoconf.h>
-#ifndef __KERNEL__
+#if !defined (__KERNEL__) && !defined(__KERNGLUE__)
 #error including kernel header in userspace; use the glibc headers instead!
 #endif
 #endif

linux-2.6-bzimage.patch:
 linux-400/arch/ia64/Makefile    |    4 ++++
 linux-500/arch/s390/Makefile    |    5 +++++
 linux-600/arch/sparc/Makefile   |    3 +++
 linux-600/arch/sparc64/Makefile |    3 +++
 4 files changed, 15 insertions(+)

--- NEW FILE linux-2.6-bzimage.patch ---
In order to make the specfile simpler, we adjust some build targets
so that every arch understands bzImage


diff -urNp --exclude-from=/home/davej/.exclude linux-400/arch/s390/Makefile linux-500/arch/s390/Makefile
--- linux-400/arch/s390/Makefile
+++ linux-500/arch/s390/Makefile
@@ -91,6 +91,11 @@ boot		:= arch/$(ARCH)/boot
 
 all: image
 
+# This is a white lie which helps to keep our spec simpler.
+# No $(Q) or other trickery because nobody should use it outside of RPM builds.
+bzImage: image
+	ln -s image arch/$(ARCH)/boot/bzImage
+
 install: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $@
 
diff -urNp --exclude-from=/home/davej/.exclude linux-503/arch/sparc/Makefile linux-600/arch/sparc/Makefile
--- linux-503/arch/sparc/Makefile
+++ linux-600/arch/sparc/Makefile
@@ -53,6 +53,9 @@ all: image
 
 boot := arch/sparc/boot
 
+bzImage: image
+	cp $(boot)/image $(boot)/bzImage
+
 image tftpboot.img: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
diff -urNp --exclude-from=/home/davej/.exclude linux-503/arch/sparc64/Makefile linux-600/arch/sparc64/Makefile
--- linux-503/arch/sparc64/Makefile
+++ linux-600/arch/sparc64/Makefile
@@ -69,6 +69,9 @@ drivers-$(CONFIG_OPROFILE)	+= arch/sparc
 
 boot := arch/sparc64/boot
 
+bzImage: image
+	cp $(boot)/image $(boot)/bzImage
+
 image tftpboot.img vmlinux.aout: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
diff -urNp --exclude-from=/home/davej/.exclude linux-302/arch/ia64/Makefile linux-400/arch/ia64/Makefile
--- linux-302/arch/ia64/Makefile
+++ linux-400/arch/ia64/Makefile
@@ -71,6 +71,10 @@ boot := arch/ia64/hp/sim/boot
 
 all: compressed unwcheck
 
+bzImage: compressed
+	mkdir -p arch/ia64/boot
+	cp vmlinux.gz arch/ia64/boot/bzImage
+
 compressed: vmlinux.gz
 
 vmlinux.gz: vmlinux


linux-2.6-crash-driver.patch:
 arch/i386/mm/init.c           |    2 
 arch/ia64/kernel/ia64_ksyms.c |    3 
 arch/x86_64/mm/init.c         |    3 
 drivers/char/Kconfig          |    2 
 drivers/char/Makefile         |    1 
 drivers/char/crash.c          |  129 ++++++++++++++++++++++++++++++++++++++++++
 include/asm-i386/crash.h      |   75 ++++++++++++++++++++++++
 include/asm-ia64/crash.h      |   90 +++++++++++++++++++++++++++++
 include/asm-x86_64/crash.h    |   75 ++++++++++++++++++++++++
 9 files changed, 380 insertions(+)

--- NEW FILE linux-2.6-crash-driver.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/i386/mm/init.c linux-1060/arch/i386/mm/init.c
--- linux-1050/arch/i386/mm/init.c
+++ linux-1060/arch/i386/mm/init.c
@@ -248,6 +248,8 @@ int devmem_is_allowed(unsigned long page
    return 0;
 }
 
+EXPORT_SYMBOL_GPL(page_is_ram);
+
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/ia64/kernel/ia64_ksyms.c linux-1060/arch/ia64/kernel/ia64_ksyms.c
--- linux-1050/arch/ia64/kernel/ia64_ksyms.c
+++ linux-1060/arch/ia64/kernel/ia64_ksyms.c
@@ -106,6 +106,9 @@ EXPORT_SYMBOL(ia64_save_scratch_fpregs);
 #include <asm/unwind.h>
 EXPORT_SYMBOL(unw_init_running);
 
+#include <linux/efi.h>
+EXPORT_SYMBOL_GPL(efi_mem_type);
+
 #ifdef ASM_SUPPORTED
 # ifdef CONFIG_SMP
 #  if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/x86_64/mm/init.c linux-1060/arch/x86_64/mm/init.c
--- linux-1050/arch/x86_64/mm/init.c
+++ linux-1060/arch/x86_64/mm/init.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -417,6 +418,8 @@ int devmem_is_allowed(unsigned long page
 }
 
 
+EXPORT_SYMBOL_GPL(page_is_ram);
+
 static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
 			 kcore_vsyscall;
 
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/drivers/char/crash.c linux-1060/drivers/char/crash.c
--- linux-1050/drivers/char/crash.c
+++ linux-1060/drivers/char/crash.c
@@ -0,0 +1,129 @@
+/*
+ *  linux/drivers/char/crash.c
+ *
+ *  Copyright (C) 2004  Dave Anderson <anderson at redhat.com>
+ *  Copyright (C) 2004  Red Hat, Inc.
+ */
+
+/******************************************************************************
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/types.h>
+#include <asm/crash.h>
+
+#define CRASH_VERSION   "1.0"
+
+/*
+ *  These are the file operation functions that allow crash utility
+ *  access to physical memory.
+ */
+
+static loff_t 
+crash_llseek(struct file * file, loff_t offset, int orig)
+{
+	switch (orig) {
+	case 0:
+		file->f_pos = offset;
+		return file->f_pos;
+	case 1:
+		file->f_pos += offset;
+		return file->f_pos;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ *  Determine the page address for an address offset value, 
+ *  get a virtual address for it, and copy it out.
+ *  Accesses must fit within a page.
+ */
+static ssize_t
+crash_read(struct file *file, char *buf, size_t count, loff_t *poff)
+{
+	void *vaddr;
+	struct page *page;
+	u64 offset;
+	ssize_t read;
+
+	offset = *poff;
+	if (offset >> PAGE_SHIFT != (offset+count-1) >> PAGE_SHIFT) 
+		return -EINVAL;
+
+	vaddr = map_virtual(offset, &page);
+	if (!vaddr)
+		return -EFAULT;
+
+	if (copy_to_user(buf, vaddr, count)) {
+		unmap_virtual(page);
+		return -EFAULT;
+	}
+	unmap_virtual(page);
+
+	read = count;
+	*poff += read;
+	return read;
+}
+
+static struct file_operations crash_fops = {
+	.owner = THIS_MODULE,
+	.llseek = crash_llseek,
+	.read = crash_read,
+};
+
+static struct miscdevice crash_dev = {
+	MISC_DYNAMIC_MINOR,
+	"crash",
+	&crash_fops
+};
+
+static int __init
+crash_init(void)
+{
+	int ret;
+
+	ret = misc_register(&crash_dev);
+	if (ret) {
+		printk(KERN_ERR 
+		    "crash memory driver: cannot misc_register (MISC_DYNAMIC_MINOR)\n");
+		goto out;
+	}
+	
+	ret = 0;
+	printk(KERN_INFO "crash memory driver: version %s\n", CRASH_VERSION);
+out:
+	return ret;
+}
+
+static void __exit
+crash_cleanup_module(void)
+{
+	misc_deregister(&crash_dev);
+}
+
+module_init(crash_init);
+module_exit(crash_cleanup_module);
+
+MODULE_LICENSE("GPL");
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/drivers/char/Kconfig linux-1060/drivers/char/Kconfig
--- linux-1050/drivers/char/Kconfig
+++ linux-1060/drivers/char/Kconfig
@@ -441,6 +441,8 @@ config LEGACY_PTYS
 	  security.  This option enables these legacy devices; on most
 	  systems, it is safe to say N.
 
+config CRASH
+        tristate "Crash Utility memory driver"
 
 config LEGACY_PTY_COUNT
 	int "Maximum number of legacy PTY in use"
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/drivers/char/Makefile linux-1060/drivers/char/Makefile
--- linux-1050/drivers/char/Makefile
+++ linux-1060/drivers/char/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_PCMCIA) += pcmcia/
 obj-$(CONFIG_IPMI_HANDLER) += ipmi/
 
 obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
+obj-$(CONFIG_CRASH) += crash.o
 obj-$(CONFIG_TCG_TPM) += tpm/
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-i386/crash.h linux-1060/include/asm-i386/crash.h
--- linux-1050/include/asm-i386/crash.h
+++ linux-1060/include/asm-i386/crash.h
@@ -0,0 +1,75 @@
+#ifndef _ASM_I386_CRASH_H
+#define _ASM_I386_CRASH_H
+
+/*
+ * linux/include/asm-i386/crash.h
+ *
+ * Copyright (c) 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/mmzone.h>
+
+extern int page_is_ram(unsigned long);
+
+static inline void *
+map_virtual(u64 offset, struct page **pp)
+{
+	struct page *page;
+	unsigned long pfn;
+	void *vaddr;
+
+	pfn = (unsigned long)(offset >> PAGE_SHIFT);
+
+	if (!page_is_ram(pfn)) {
+		printk(KERN_INFO
+		    "crash memory driver: !page_is_ram(pfn: %lx)\n", pfn);
+		return NULL;
+	}
+
+	if (!pfn_valid(pfn)) {
+		printk(KERN_INFO
+		    "crash memory driver: invalid pfn: %lx )\n", pfn);
+		return NULL;
+	}
+
+	page = pfn_to_page(pfn);
+
+	vaddr = kmap(page);
+	if (!vaddr) {
+		printk(KERN_INFO
+		    "crash memory driver: pfn: %lx kmap(page: %lx) failed\n", 
+			pfn, (unsigned long)page);
+		return NULL;
+	}
+
+	*pp = page;
+	return (vaddr + (offset & (PAGE_SIZE-1)));
+}
+
+static inline void unmap_virtual(struct page *page) 
+{ 
+	kunmap(page);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_I386_CRASH_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-ia64/crash.h linux-1060/include/asm-ia64/crash.h
--- linux-1050/include/asm-ia64/crash.h
+++ linux-1060/include/asm-ia64/crash.h
@@ -0,0 +1,90 @@
+#ifndef _ASM_IA64_CRASH_H
+#define _ASM_IA64_CRASH_H
+
+/*
+ * linux/include/asm-ia64/crash.h
+ *
+ * Copyright (c) 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/efi.h>
+#include <linux/mm.h>
+#include <asm/mmzone.h>
+
+static inline void *
+map_virtual(u64 offset, struct page **pp)
+{
+	struct page *page;
+	unsigned long pfn;
+	u32 type;
+
+	if (REGION_NUMBER(offset) == 5) {
+		char byte;
+
+		if (__get_user(byte, (char *)offset) == 0)
+			return (void *)offset;
+		else
+			return NULL;
+	}
+
+	switch (type = efi_mem_type(offset)) 
+	{
+	case EFI_LOADER_CODE:
+	case EFI_LOADER_DATA:
+	case EFI_BOOT_SERVICES_CODE:
+	case EFI_BOOT_SERVICES_DATA:
+	case EFI_CONVENTIONAL_MEMORY:
+		break;
+
+	default:
+		printk(KERN_INFO
+		    "crash memory driver: invalid memory type for %lx: %d\n", 
+			offset, type);
+		return NULL;
+	}
+
+	pfn = offset >> PAGE_SHIFT;
+
+	if (!pfn_valid(pfn)) {
+		printk(KERN_INFO
+			"crash memory driver: invalid pfn: %lx )\n", pfn);
+		return NULL;
+	}
+
+	page = pfn_to_page(pfn);
+
+	if (!page->virtual) {
+		printk(KERN_INFO
+		    "crash memory driver: offset: %lx page: %lx page->virtual: NULL\n", 
+			offset, (unsigned long)page);
+		return NULL;
+	}
+
+	return (page->virtual + (offset & (PAGE_SIZE-1)));
+}
+
+static inline void unmap_virtual(struct page *page) 
+{ 
+	return;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IA64_CRASH_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-x86_64/crash.h linux-1060/include/asm-x86_64/crash.h
--- linux-1050/include/asm-x86_64/crash.h
+++ linux-1060/include/asm-x86_64/crash.h
@@ -0,0 +1,75 @@
+#ifndef _ASM_X86_64_CRASH_H
+#define _ASM_X86_64_CRASH_H
+
+/*
+ * linux/include/asm-x86_64/crash.h
+ *
+ * Copyright (c) 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/mmzone.h>
+
+extern int page_is_ram(unsigned long);
+
+static inline void *
+map_virtual(u64 offset, struct page **pp)
+{
+	struct page *page;
+	unsigned long pfn;
+	void *vaddr;
+
+	pfn = (unsigned long)(offset >> PAGE_SHIFT);
+
+	if (!page_is_ram(pfn)) {
+		printk(KERN_INFO
+		    "crash memory driver: !page_is_ram(pfn: %lx)\n", pfn);
+		return NULL;
+	}
+
+	if (!pfn_valid(pfn)) {
+		printk(KERN_INFO
+		    "crash memory driver: invalid pfn: %lx )\n", pfn);
+		return NULL;
+	}
+
+	page = pfn_to_page(pfn);
+
+	vaddr = kmap(page);
+	if (!vaddr) {
+		printk(KERN_INFO
+		    "crash memory driver: pfn: %lx kmap(page: %lx) failed\n", 
+			pfn, (unsigned long)page);
+		return NULL;
+	}
+
+	*pp = page;
+	return (vaddr + (offset & (PAGE_SIZE-1)));
+}
+
+static inline void unmap_virtual(struct page *page) 
+{ 
+	kunmap(page);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_X86_64_CRASH_H */

linux-2.6-crash-xen.patch:
 init.c |    2 ++
 1 files changed, 2 insertions(+)

--- NEW FILE linux-2.6-crash-xen.patch ---
Fix up xen for crash driver in rawhide
---

 arch/i386/xen/mm/init.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/i386/xen/mm/init.c b/arch/i386/xen/mm/init.c
index 4c8c7ac..caf4afd 100644
--- a/arch/i386/xen/mm/init.c
+++ b/arch/i386/xen/mm/init.c
@@ -281,6 +281,8 @@ int page_is_ram(unsigned long pagenr)
 
 #endif
 
+EXPORT_SYMBOL_GPL(page_is_ram);
+
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
 pgprot_t kmap_prot;

linux-2.6-crashdump-common.patch:
 linux-2.6.12/Documentation/sysrq.txt         |    8 
 linux-2.6.12/arch/i386/kernel/nmi.c          |    1 
 linux-2.6.12/arch/i386/kernel/traps.c        |    3 
 linux-2.6.12/arch/i386/mm/init.c             |   47 +++++
 linux-2.6.12/arch/i386/mm/pgtable.c          |    3 
 linux-2.6.12/arch/ia64/kernel/process.c      |   30 ++-
 linux-2.6.12/arch/ia64/kernel/traps.c        |    6 
 linux-2.6.12/arch/ia64/mm/contig.c           |    3 
 linux-2.6.12/arch/ia64/mm/discontig.c        |    3 
 linux-2.6.12/arch/ia64/mm/init.c             |   90 +++++++++
 linux-2.6.12/arch/powerpc/kernel/process.c   |    1 
 linux-2.6.12/arch/powerpc/kernel/traps.c     |    3 
 linux-2.6.12/arch/powerpc/mm/mem.c           |   29 +++
 linux-2.6.12/arch/s390/kernel/traps.c        |    6 
 linux-2.6.12/arch/x86_64/kernel/process.c    |    2 
 linux-2.6.12/arch/x86_64/kernel/traps.c      |    6 
 linux-2.6.12/arch/x86_64/mm/init.c           |   32 +++
 linux-2.6.12/drivers/char/sysrq.c            |   13 +
 linux-2.6.12/include/asm-generic/crashdump.h |   47 +++++
 linux-2.6.12/include/asm-i386/crashdump.h    |  123 +++++++++++++
 linux-2.6.12/include/asm-i386/kmap_types.h   |    4 
 linux-2.6.12/include/asm-ia64/crashdump.h    |   72 +++++++
 linux-2.6.12/include/asm-powerpc/crashdump.h |   61 ++++++
 linux-2.6.12/include/asm-x86_64/crashdump.h  |   86 +++++++++
 linux-2.6.12/include/linux/kernel.h          |   18 +
 linux-2.6.12/kernel/Makefile                 |    2 
 linux-2.6.12/kernel/dump.c                   |  246 +++++++++++++++++++++++++++
 linux-2.6.12/kernel/panic.c                  |    4 
 linux-2.6.12/kernel/printk.c                 |   20 ++
 linux-2.6.12/kernel/sched.c                  |    2 
 linux-2.6.13/arch/x86_64/mm/fault.c          |    1 
 linux-2.6.13/drivers/char/sysrq.c            |    5 
 32 files changed, 963 insertions(+), 14 deletions(-)

--- NEW FILE linux-2.6-crashdump-common.patch ---
--- linux-2.6.12/drivers/char/sysrq.c.orig	2005-08-18 12:40:07.000000000 -0400
+++ linux-2.6.12/drivers/char/sysrq.c	2005-08-18 14:29:25.000000000 -0400
@@ -125,6 +125,17 @@
 	.enable_mask	= SYSRQ_ENABLE_BOOT,
 };
 
+/* crash sysrq handler */
+static void sysrq_handle_crash(int key, struct pt_regs *pt_regs,
+			       struct tty_struct *tty) {
+	*( (char *) 0) = 0;
+}
+static struct sysrq_key_op sysrq_crash_op = {
+	.handler =       sysrq_handle_crash,
+	.help_msg =      "Crash",
+	.action_msg =    "Crashing the kernel by request",
+};
+
 static void sysrq_handle_sync(int key, struct pt_regs *pt_regs,
 			      struct tty_struct *tty) 
 {
@@ -289,7 +300,7 @@
 		 it is handled specially on the sparc
 		 and will never arrive */
 /* b */	&sysrq_reboot_op,
-#ifdef CONFIG_KEXEC
+#if defined(CONFIG_KEXEC) || defined(CONFIG_NETDUMP) || defined(CONFIG_DISKDUMP)
 /* c */ &sysrq_crashdump_op,
 #else
 /* c */	NULL,
--- /dev/null	2005-08-18 08:15:49.820487896 -0400
+++ linux-2.6.12/include/asm-ia64/crashdump.h	2005-08-18 14:23:59.000000000 -0400
@@ -0,0 +1,72 @@
+#ifndef _ASM_IA64_CRASHDUMP_H
+#define _ASM_IA64_CRASHDUMP_H
+
+/*
+ * linux/include/asm-ia64/crashdump.h
+ *
+ * Copyright (c) 2004 FUJITSU LIMITED
+ * Copyright (c) 2003 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/elf.h>
+#include <asm/unwind.h>
+#include <asm/ptrace.h>
+
+extern void ia64_do_copy_regs(struct unw_frame_info *, void *arg);
+extern void ia64_freeze_cpu(struct unw_frame_info *, void *arg);
+extern void ia64_start_dump(struct unw_frame_info *, void *arg);
+extern int page_is_ram(unsigned long);
+extern unsigned long next_ram_page(unsigned long);
+
+#define platform_timestamp(x) ({ x = ia64_get_itc(); })
+
+#define platform_fix_regs()					\
+{								\
+	struct unw_frame_info *info = platform_arg;		\
+								\
+	current->thread.ksp = (__u64)info->sw - 16;		\
+	myregs = *regs;						\
+}
+
+#define platform_init_stack(stackptr) do { } while (0)
+#define platform_cleanup_stack(stackptr) do { } while (0)
+
+typedef asmlinkage void (*crashdump_func_t)(struct pt_regs *, void *);
+
+/* Container to hold dump hander information */
+struct dump_call_param {
+	crashdump_func_t func;
+	struct pt_regs	*regs;
+};
+
+static inline void platform_start_crashdump(void *stackptr,
+					    crashdump_func_t dumpfunc,
+					    struct pt_regs *regs)
+{
+	struct dump_call_param param;
+
+	param.func = dumpfunc;
+	param.regs = regs;
+	unw_init_running(ia64_start_dump, &param);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IA64_CRASHDUMP_H */
--- /dev/null	2005-08-18 08:15:49.820487896 -0400
+++ linux-2.6.12/include/asm-powerpc/crashdump.h	2005-08-18 14:23:59.000000000 -0400
@@ -0,0 +1,61 @@
+#ifndef _ASM_POWERPC_CRASHDUMP_H
+#define _ASM_POWERPC_CRASHDUMP_H
+
+/*
+ * linux/include/asm-powerpc/crashdump.h
+ *
+ * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/time.h>
+
+extern int page_is_ram (unsigned long);
+extern unsigned long next_ram_page (unsigned long);
+
+#define platform_timestamp(x) (x = get_tb())
+
+#define platform_fix_regs()						\
+{									\
+       memcpy(&myregs, regs, sizeof(struct pt_regs));			\
+};
+
+#define platform_init_stack(stackptr) do { } while (0)
+#define platform_cleanup_stack(stackptr) do { } while (0)
+
+typedef asmlinkage void (*crashdump_func_t)(struct pt_regs *, void *);
+
+static inline void platform_start_crashdump(void *stackptr,
+					   crashdump_func_t dumpfunc,
+					   struct pt_regs *regs)
+{
+	dumpfunc(regs, NULL);
+}
+
+#define platform_freeze_cpu()					\
+{								\
+	current->thread.ksp = __get_SP();			\
+	for (;;) local_irq_disable();				\
+}
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_POWERPC_CRASHDUMP_H */
--- /dev/null	2005-08-18 08:15:49.820487896 -0400
+++ linux-2.6.12/include/asm-x86_64/crashdump.h	2005-08-18 14:23:59.000000000 -0400
@@ -0,0 +1,86 @@
+/*
+ * include/asm-x86_64/crashdump.h
+ *
+ * Copyright (C) Hitachi, Ltd. 2004
+ * Written by Satoshi Oshima (oshima at sdl.hitachi.co.jp)
+ *
+ * Derived from include/asm-i386/diskdump.h
+ * Copyright (c) 2004 FUJITSU LIMITED
+ * Copyright (c) 2003 Red Hat, Inc. All rights reserved.
+ *
+ */
+
+#ifndef _ASM_X86_64_CRASHDUMP_H
+#define _ASM_X86_64_CRASHDUMP_H
+
+#ifdef __KERNEL__
+
+#include <linux/elf.h>
+
+extern int page_is_ram(unsigned long);
+extern unsigned long next_ram_page(unsigned long);
+
+#define platform_fix_regs() \
+{                                                                      \
+       unsigned long rsp;                                              \
+       unsigned short ss;                                              \
+       rsp = (unsigned long) ((char *)regs + sizeof (struct pt_regs)); \
+       ss = __KERNEL_DS;                                               \
+       if (regs->cs & 3) {                                             \
+               rsp = regs->rsp;                                        \
+               ss = regs->ss & 0xffff;                                 \
+       }                                                               \
+       myregs = *regs;                                                 \
+       myregs.rsp = rsp;                                               \
+       myregs.ss = (myregs.ss & (~0xffff)) | ss;                       \
+}
+
+#define platform_timestamp(x) rdtscll(x)
+
+#define platform_freeze_cpu()					\
+{								\
+	for (;;) local_irq_disable();				\
+}
+
+static inline void platform_init_stack(void **stackptr)
+{
+	struct page *page;
+
+	if ((page = alloc_page(GFP_KERNEL)))
+		*stackptr = (void *)page_address(page);
+
+	if (*stackptr)
+		memset(*stackptr, 0, PAGE_SIZE);
+	else
+		printk(KERN_WARNING
+		    "crashdump: unable to allocate separate stack\n");
+}
+
+#define platform_cleanup_stack(stackptr)               \
+do {                                                   \
+	if (stackptr)                                  \
+		free_page((unsigned long)stackptr);    \
+} while (0)
+
+typedef asmlinkage void (*crashdump_func_t)(struct pt_regs *, void *);
+
+static inline void platform_start_crashdump(void *stackptr,
+					    crashdump_func_t dumpfunc,
+					    struct pt_regs *regs)
+{								
+	static unsigned long old_rsp;
+	unsigned long new_rsp;
+
+	if (stackptr) {
+		asm volatile("movq %%rsp,%0" : "=r" (old_rsp));
+		new_rsp = (unsigned long)stackptr + PAGE_SIZE;
+		asm volatile("movq %0,%%rsp" :: "r" (new_rsp));
+		dumpfunc(regs, NULL);
+		asm volatile("movq %0,%%rsp" :: "r" (old_rsp));
+	} else
+		dumpfunc(regs, NULL);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_X86_64_CRASHDUMP_H */
--- linux-2.6.12/include/asm-i386/kmap_types.h.orig	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/include/asm-i386/kmap_types.h	2005-08-18 14:23:59.000000000 -0400
@@ -23,7 +23,9 @@
 D(10)	KM_IRQ1,
 D(11)	KM_SOFTIRQ0,
 D(12)	KM_SOFTIRQ1,
-D(13)	KM_TYPE_NR
+D(13)	KM_CRASHDUMP,
+D(14)	KM_UNUSED,
+D(15)	KM_TYPE_NR
 };
 
 #undef D
--- /dev/null	2005-08-18 08:15:49.820487896 -0400
+++ linux-2.6.12/include/asm-i386/crashdump.h	2005-08-18 14:23:59.000000000 -0400
@@ -0,0 +1,123 @@
+#ifndef _ASM_I386_CRASHDUMP_H
+#define _ASM_I386_CRASHDUMP_H
+
+/*
+ * linux/include/asm-i386/crashdump.h
+ *
+ * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/irq.h>
+
+/*
+ *  Structure taken from arch/i386/kernel/irq.c.  It used to live in asm/irq.h.
+ */
+#ifdef CONFIG_4KSTACKS
+union dump_irq_ctx {
+	struct thread_info	tinfo;
+	u32			stack[THREAD_SIZE/sizeof(u32)];
+};
+#endif
+
+extern int page_is_ram (unsigned long);
+extern unsigned long next_ram_page (unsigned long);
+
+#define platform_timestamp(x) rdtscll(x)
+
+#define platform_fix_regs()						\
+{									\
+       unsigned long esp;						\
+       unsigned short ss;						\
+       esp = (unsigned long) ((char *)regs + sizeof (struct pt_regs));	\
+       ss = __KERNEL_DS;						\
+       if (regs->xcs & 3) {						\
+               esp = regs->esp;						\
+               ss = regs->xss & 0xffff;					\
+       }								\
+       myregs = *regs;							\
+       myregs.esp = esp;						\
+       myregs.xss = (myregs.xss & 0xffff0000) | ss;			\
+};
+
+static inline void platform_init_stack(void **stackptr)
+{
+#ifdef CONFIG_4KSTACKS
+	*stackptr = (void *)kmalloc(sizeof(union dump_irq_ctx), GFP_KERNEL);
+	if (*stackptr)
+		memset(*stackptr, 0, sizeof(union dump_irq_ctx));
+	else
+		printk(KERN_WARNING
+		       "crashdump: unable to allocate separate stack\n");
+#else
+	*stackptr = NULL;
+#endif
+}
+
+typedef asmlinkage void (*crashdump_func_t)(struct pt_regs *, void *);
+
+static inline void platform_start_crashdump(void *stackptr,
+					   crashdump_func_t dumpfunc,
+					   struct pt_regs *regs)
+{
+	if (!stackptr)
+		dumpfunc(regs, NULL);
+#ifdef CONFIG_4KSTACKS
+	else {
+		u32 *dsp;
+		union dump_irq_ctx * curctx;
+		union dump_irq_ctx * dumpctx;
+
+		curctx = (union dump_irq_ctx *) current_thread_info();
+		dumpctx = (union dump_irq_ctx *) stackptr;
+
+		/* build the stack frame on the IRQ stack */
+		dsp = (u32*) ((char*)dumpctx + sizeof(*dumpctx));
+		dumpctx->tinfo.task = curctx->tinfo.task;
+		dumpctx->tinfo.previous_esp = current_stack_pointer;
+
+		*--dsp = (u32) NULL;
+		*--dsp = (u32) regs;
+
+		asm volatile(
+			"       xchgl   %%ebx,%%esp     \n"
+			"	call    *%%eax          \n"
+			"	xchgl   %%ebx,%%esp     \n"
+			: : "a"(dumpfunc), "b"(dsp)
+			: "memory", "cc", "edx", "ecx"
+		);
+	}
+#endif
+}
+
+#define platform_cleanup_stack(stackptr)	\
+do {						\
+	if (stackptr)				\
+		kfree(stackptr);		\
+} while (0)
+
+#define platform_freeze_cpu()					\
+{								\
+	for (;;) local_irq_disable();				\
+}
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_I386_CRASHDUMP_H */
--- linux-2.6.12/include/linux/kernel.h.orig	2005-08-18 12:41:12.000000000 -0400
+++ linux-2.6.12/include/linux/kernel.h	2005-08-18 14:23:59.000000000 -0400
@@ -175,6 +175,17 @@
 extern void add_taint(unsigned);
 extern int check_tainted(void);
 
+#define crashdump_mode()       unlikely(netdump_mode || diskdump_mode)
+
+struct pt_regs;
+extern void try_crashdump(struct pt_regs *);
+extern void (*netdump_func) (struct pt_regs *regs);
+extern int netdump_mode;
+extern void (*diskdump_func) (struct pt_regs *regs);
+extern int diskdump_mode;
+
+#define crashdump_func()	unlikely(netdump_func || diskdump_func)
+
 /* Values used for system_state */
 extern enum system_states {
 	SYSTEM_BOOTING,
@@ -182,6 +193,7 @@
 	SYSTEM_HALT,
 	SYSTEM_POWER_OFF,
 	SYSTEM_RESTART,
+	SYSTEM_DUMPING,
 } system_state;
 
 #define TAINT_PROPRIETARY_MODULE	(1<<0)
@@ -204,6 +216,12 @@
 #define pr_info(fmt,arg...) \
 	printk(KERN_INFO fmt,##arg)
 
+#define pr_err(fmt,arg...) \
+	printk(KERN_ERR fmt,##arg)
+
+#define pr_warn(fmt,arg...) \
+	printk(KERN_WARNING fmt,##arg)
+
 /*
  *      Display an IP address in readable format.
  */
--- /dev/null	2005-08-18 08:15:49.820487896 -0400
+++ linux-2.6.12/include/asm-generic/crashdump.h	2005-08-18 14:23:59.000000000 -0400
@@ -0,0 +1,47 @@
+#ifndef _ASM_GENERIC_CRASHDUMP_H_
+#define _ASM_GENERIC_CRASHDUMP_H_
+
+/*
+ * linux/include/asm-generic/crashdump.h
+ *
+ * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __KERNEL__
+
+#define platform_timestamp(x) do { (x) = 0; } while (0)  
+
+#define platform_fix_regs() do { } while (0)
+#define platform_init_stack(stackptr) do { } while (0)
+#define platform_cleanup_stack(stackptr) do { } while (0)
+#define platform_start_crashdump(stackptr,dumpfunc,regs) (0)
+
+#undef ELF_CORE_COPY_REGS
+#define ELF_CORE_COPY_REGS(x, y) do { struct pt_regs *z; z = (y); } while (0)
+
+#define show_mem() do {} while (0)
+
+#define show_state() do {} while (0)
+
+#define show_regs(x) do { struct pt_regs *z; z = (x); } while (0)
+
+#undef KM_CRASHDUMP
+#define KM_CRASHDUMP 0
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_GENERIC_CRASHDUMP_H */
--- linux-2.6.12/Documentation/sysrq.txt.orig	2005-08-18 12:39:53.000000000 -0400
+++ linux-2.6.12/Documentation/sysrq.txt	2005-08-18 14:23:59.000000000 -0400
@@ -74,6 +74,10 @@
 
 'c'	- Will perform a kexec reboot in order to take a crashdump.
 
+'c'     - Intentionally crash the system without syncing or unmounting
+          your disks.  This is most useful if the NETDUMP client package
+          and/or the DISKDUMP package have been installed.
+
 'o'     - Will shut your system off (if configured and supported).
 
 's'     - Will attempt to sync all mounted filesystems.
@@ -127,6 +131,10 @@
 'C'rashdump can be used to manually trigger a crashdump when the system is hung.
 The kernel needs to have been built with CONFIG_KEXEC enabled.
 
+'C'rash immediately crashes your system.  This is most useful if the machine
+has been configured as a NETDUMP client because an OOPS report is generated
+and a kernel crash dump is sent to the NETDUMP server.
+
 'S'ync is great when your system is locked up, it allows you to sync your
 disks and will certainly lessen the chance of data loss and fscking. Note
 that the sync hasn't taken place until you see the "OK" and "Done" appear
--- /dev/null	2005-08-18 08:15:49.820487896 -0400
+++ linux-2.6.12/kernel/dump.c	2005-08-18 14:23:59.000000000 -0400
@@ -0,0 +1,246 @@
+/*
+ *  linux/kernel/dump.c
+ *
+ *  Copyright (C) 2004  FUJITSU LIMITED
+ *  Written by Nobuhiro Tachino (ntachino at jp.fujitsu.com)
+ *
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/nmi.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/genhd.h>
+#include <linux/diskdump.h>
+#include <asm/diskdump.h>
+
+static DECLARE_MUTEX(dump_ops_mutex);
+struct disk_dump_ops* dump_ops = NULL;
+
+int diskdump_mode = 0;
+EXPORT_SYMBOL_GPL(diskdump_mode);
+
+void (*diskdump_func) (struct pt_regs *regs) = NULL;
+EXPORT_SYMBOL_GPL(diskdump_func);
+
+static unsigned long long timestamp_base;
+static unsigned long timestamp_hz;
+
+
+/*
+ * register/unregister diskdump operations
+ */
+int diskdump_register_ops(struct disk_dump_ops* op)
+{
+	down(&dump_ops_mutex);
+	if (dump_ops) {
+		up(&dump_ops_mutex);
+		return -EEXIST;
+	}
+	dump_ops = op;
+	up(&dump_ops_mutex);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(diskdump_register_ops);
+
+void diskdump_unregister_ops(void)
+{
+	down(&dump_ops_mutex);
+	dump_ops = NULL;
+	up(&dump_ops_mutex);
+}
+
+EXPORT_SYMBOL_GPL(diskdump_unregister_ops);
+
+
+/*
+ * sysfs interface
+ */
+static struct gendisk *device_to_gendisk(struct device *dev)
+{
+	struct dentry *d;
+	struct qstr qstr;
+
+	/* trace symlink to "block" */
+	qstr.name = "block";
+	qstr.len = strlen(qstr.name);
+	qstr.hash = full_name_hash(qstr.name, qstr.len);
+	d = d_lookup(dev->kobj.dentry, &qstr);
+	if (!d || !d->d_fsdata)
+		return NULL;
+	else
+		return container_of(d->d_fsdata, struct gendisk, kobj);
+}
+
+ssize_t diskdump_sysfs_store(struct device *dev, const char *buf, size_t count)
+{
+	struct gendisk *disk;
+	struct block_device *bdev;
+	int part, remove = 0;
+
+	if (!dump_ops || !dump_ops->add_dump || !dump_ops->remove_dump)
+		return count;
+
+	/* get partition number */
+	sscanf (buf, "%d\n", &part);
+	if (part < 0) {
+		part = -part;
+		remove = 1;
+	}
+
+	/* get block device */
+	if (!(disk = device_to_gendisk(dev)) ||
+	    !(bdev = bdget_disk(disk, part)))
+		return count;
+
+	/* add/remove device */
+	down(&dump_ops_mutex);
+	if (!remove)
+		dump_ops->add_dump(dev, bdev);
+	else
+		dump_ops->remove_dump(bdev);
+	up(&dump_ops_mutex);
+
+	return count;
+}
+
+EXPORT_SYMBOL_GPL(diskdump_sysfs_store);
+
+ssize_t diskdump_sysfs_show(struct device *dev, char *buf)
+{
+	struct gendisk *disk;
+	struct block_device *bdev;
+	int part, tmp, len = 0, maxlen = 1024;
+	char* p = buf; 
+	char name[BDEVNAME_SIZE];
+
+	if (!dump_ops || !dump_ops->find_dump)
+		return 0;
+
+	/* get gendisk */
+	disk = device_to_gendisk(dev);
+	if (!disk || !disk->part)
+		return 0;
+
+	/* print device */
+	down(&dump_ops_mutex);
+	for (part = 0; part < disk->minors - 1; part++) {
+		bdev = bdget_disk(disk, part);
+		if (dump_ops->find_dump(bdev)) {
+			tmp = sprintf(p, "%s\n", bdevname(bdev, name));
+			len += tmp;
+			p += tmp;
+		}
+		bdput(bdev);
+		if(len >= maxlen)
+			break;
+	}
+	up(&dump_ops_mutex);
+
+	return len;
+}
+
+EXPORT_SYMBOL_GPL(diskdump_sysfs_show);
+
+/*
+ * run timer/tasklet/workqueue during dump
+ */
+void diskdump_setup_timestamp(void)
+{
+	unsigned long long t;
+
+	platform_timestamp(timestamp_base);
+	udelay(1000000/HZ);
+	platform_timestamp(t);
+	timestamp_hz = (unsigned long)(t - timestamp_base);
+	diskdump_update();
+}
+
+EXPORT_SYMBOL_GPL(diskdump_setup_timestamp);
+
+void diskdump_update(void)
+{
+	unsigned long long t;
+
+	touch_nmi_watchdog();
+
+	/* update jiffies */
+	platform_timestamp(t);
+	while (t > timestamp_base + timestamp_hz) {
+		timestamp_base += timestamp_hz;
+		jiffies++;
+		platform_timestamp(t);
+	}
+
+	dump_run_timers();
+	dump_run_tasklet();
+	dump_run_workqueue();
+}
+
+EXPORT_SYMBOL_GPL(diskdump_update);
+
+
+/*
+ * register/unregister hook
+ */
+int diskdump_register_hook(void (*dump_func) (struct pt_regs *))
+{
+	if (diskdump_func)
+		return -EEXIST;
+
+	diskdump_func = dump_func;
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(diskdump_register_hook);
+
+void diskdump_unregister_hook(void)
+{
+	diskdump_func = NULL;
+}
+
+EXPORT_SYMBOL_GPL(diskdump_unregister_hook);
+
+void (*netdump_func) (struct pt_regs *regs) = NULL;
+int netdump_mode = 0;
+EXPORT_SYMBOL_GPL(netdump_mode);
+
+/*
+ * Try crashdump. Diskdump is first, netdump is second.
+ * We clear diskdump_func before call of diskdump_func, so
+ * If double panic would occur in diskdump, netdump can handle
+ * it.
+ */
+void try_crashdump(struct pt_regs *regs)
+{
+	void (*func)(struct pt_regs *);
+
+	if (diskdump_func) {
+		func = diskdump_func;
+		diskdump_func = NULL;
+		func(regs);
+	}
+	if (netdump_func)
+		netdump_func(regs);
+}
--- linux-2.6.12/kernel/printk.c.orig	2005-08-18 12:40:55.000000000 -0400
+++ linux-2.6.12/kernel/printk.c	2005-08-18 14:23:59.000000000 -0400
@@ -357,6 +357,20 @@
 }
 
 /*
+ * Crashdump special routine. Don't print to global log_buf, just to the
+ * actual console device(s).
+ */
+static void crashdump_call_console_drivers(const char *buf, unsigned long len)
+{
+	struct console *con;
+
+	for (con = console_drivers; con; con = con->next) {
+		if ((con->flags & CON_ENABLED) && con->write)
+			con->write(con, buf, len);
+	}
+}
+
+/*
  * Call the console drivers on a range of log_buf
  */
 static void __call_console_drivers(unsigned long start, unsigned long end)
@@ -531,6 +545,12 @@
 	/* Emit the output into the temporary buffer */
 	printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
 
+	if (unlikely(crashdump_mode())) {
+		crashdump_call_console_drivers(printk_buf, printed_len);
+		spin_unlock_irqrestore(&logbuf_lock, flags);
+		goto out;
+	}
+
 	/*
 	 * Copy the output into log_buf.  If the caller didn't provide
 	 * appropriate log level tags, we insert them here
--- linux-2.6.12/kernel/Makefile.orig	2005-08-18 12:41:10.000000000 -0400
+++ linux-2.6.12/kernel/Makefile	2005-08-18 14:23:59.000000000 -0400
@@ -7,7 +7,7 @@
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
-	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
+	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o dump.o
 
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
--- linux-2.6.12/kernel/sched.c.orig	2005-08-18 12:41:14.000000000 -0400
+++ linux-2.6.12/kernel/sched.c	2005-08-18 14:32:27.000000000 -0400
@@ -4177,6 +4177,8 @@
 	read_unlock(&tasklist_lock);
 }
 
+EXPORT_SYMBOL_GPL(show_state);
+
 /**
  * init_idle - set up an idle thread for a given CPU
  * @idle: task in question
--- linux-2.6.12/kernel/panic.c.orig	2005-08-18 12:41:17.000000000 -0400
+++ linux-2.6.12/kernel/panic.c	2005-08-18 14:31:42.000000000 -0400
@@ -89,6 +89,10 @@
  	dump_stack();
 	bust_spinlocks(0);
 
+#if defined(CONFIG_NETDUMP) || defined(CONFIG_DISKDUMP)
+	if (crashdump_func())
+		BUG();
+#endif
 	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
 	 * everything else.
--- linux-2.6.12/arch/s390/kernel/traps.c.orig	2005-08-18 12:40:01.000000000 -0400
+++ linux-2.6.12/arch/s390/kernel/traps.c	2005-08-18 14:23:59.000000000 -0400
@@ -286,12 +286,16 @@
 	bust_spinlocks(1);
 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
         show_regs(regs);
+	try_crashdump(regs);  
 	bust_spinlocks(0);
         spin_unlock_irq(&die_lock);
 	if (in_interrupt())
 		panic("Fatal exception in interrupt");
-	if (panic_on_oops)
+	if (panic_on_oops) {
+		if (netdump_func)
+			netdump_func = NULL;
 		panic("Fatal exception: panic_on_oops");
+	}
         do_exit(SIGSEGV);
 }
 
--- linux-2.6.12/arch/i386/mm/init.c.orig	2005-08-18 12:41:14.000000000 -0400
+++ linux-2.6.12/arch/i386/mm/init.c	2005-08-18 14:23:58.000000000 -0400
@@ -229,6 +229,53 @@
 	return 0;
 }
 
+unsigned long next_ram_page(unsigned long pagenr)
+{
+	int i;
+	unsigned long addr, end;
+	unsigned long min_pageno = ULONG_MAX;
+
+	pagenr++;
+
+	if (efi_enabled) {
+		efi_memory_desc_t *md;
+
+		for (i = 0; i < memmap.nr_map; i++) {
+			md = &memmap.map[i];
+			if (!is_available_memory(md))
+				continue;
+			addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT;
+			end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT;
+
+			if ((pagenr >= addr) && (pagenr < end))
+				return pagenr;
+			if ((pagenr < addr) && (addr < min_pageno))
+				min_pageno = addr;
+		}
+		return min_pageno;
+	}
+
+	for (i = 0; i < e820.nr_map; i++) {
+
+		if (e820.map[i].type != E820_RAM)	/* not usable memory */
+			continue;
+		/*
+		 *	!!!FIXME!!! Some BIOSen report areas as RAM that
+		 *	are not. Notably the 640->1Mb area. We need a sanity
+		 *	check here.
+		 */
+		addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
+		end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
+		if  ((pagenr >= addr) && (pagenr < end))
+			return pagenr;
+		if ((pagenr < addr) && (addr < min_pageno))
+			min_pageno = addr;
+	}
+	return min_pageno;
+}
+
+EXPORT_SYMBOL_GPL(next_ram_page);
+
 /*
  * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
  * valid. The argument is a physical page number.
--- linux-2.6.12/arch/i386/mm/pgtable.c.orig	2005-08-18 12:39:56.000000000 -0400
+++ linux-2.6.12/arch/i386/mm/pgtable.c	2005-08-18 14:23:58.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -63,6 +64,8 @@
 	printk(KERN_INFO "%lu pages pagetables\n", ps.nr_page_table_pages);
 }
 
+EXPORT_SYMBOL_GPL(show_mem);
+
 /*
  * Associate a virtual page frame with a given physical page frame 
  * and protection flags for that frame.
--- linux-2.6.12/arch/i386/kernel/traps.c.orig	2005-08-18 14:09:19.000000000 -0400
+++ linux-2.6.12/arch/i386/kernel/traps.c	2005-08-18 14:10:35.000000000 -0400
@@ -342,6 +342,7 @@
 			printk("\n");
 	notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
 		show_registers(regs);
+		try_crashdump(regs);
   	} else
 		printk(KERN_ERR "Recursive die() failure, output suppressed\n");
 
@@ -356,6 +357,8 @@
 		panic("Fatal exception in interrupt");
 
 	if (panic_on_oops) {
+		if (netdump_func)
+			netdump_func = NULL;
 		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
 		ssleep(5);
 		panic("Fatal exception");
--- linux-2.6.12/arch/i386/kernel/nmi.c.orig	2005-08-18 14:06:49.000000000 -0400
+++ linux-2.6.12/arch/i386/kernel/nmi.c	2005-08-18 14:06:56.000000000 -0400
@@ -577,3 +577,4 @@
 EXPORT_SYMBOL(release_lapic_nmi);
 EXPORT_SYMBOL(disable_timer_nmi_watchdog);
 EXPORT_SYMBOL(enable_timer_nmi_watchdog);
+EXPORT_SYMBOL(touch_nmi_watchdog);
--- linux-2.6.13/arch/x86_64/mm/fault.c~	2005-09-13 00:42:55.000000000 -0400
+++ linux-2.6.13/arch/x86_64/mm/fault.c	2005-09-13 00:43:20.000000000 -0400
@@ -536,6 +536,7 @@ no_context:
 	__die("Oops", regs, error_code);
 	/* Executive summary in case the body of the oops scrolled away */
 	printk(KERN_EMERG "CR2: %016lx\n", address);
+	try_crashdump(regs);
 	oops_end(flags);
 	do_exit(SIGKILL);
 
--- linux-2.6.12/arch/x86_64/mm/init.c.orig	2005-08-18 12:41:25.000000000 -0400
+++ linux-2.6.12/arch/x86_64/mm/init.c	2005-08-18 14:23:59.000000000 -0400
@@ -85,6 +86,8 @@
 	printk("%d pages swap cached\n",cached);
 }
 
+EXPORT_SYMBOL_GPL(show_mem);
+
 /* References to section boundaries */
 
 extern char _text, _etext, _edata, __bss_start, _end[];
@@ -398,6 +401,35 @@
 
 extern int swiotlb_force;
 
+unsigned long next_ram_page (unsigned long pagenr)
+{
+	int i;
+	unsigned long min_pageno = ULONG_MAX;
+
+	pagenr++;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		unsigned long addr, end;
+
+		if (e820.map[i].type != E820_RAM)	/* not usable memory */
+			continue;
+		/*
+		 *	!!!FIXME!!! Some BIOSen report areas as RAM that
+		 *	are not. Notably the 640->1Mb area. We need a sanity
+		 *	check here.
+		 */
+		addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
+		end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
+		if  ((pagenr >= addr) && (pagenr < end))
+			return pagenr;
+		if ((pagenr < addr) && (addr < min_pageno))
+			min_pageno = addr;
+	}
+	return min_pageno;
+}
+
+EXPORT_SYMBOL_GPL(next_ram_page);
+
 /*
  * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
  * valid. The argument is a physical page number.
@@ -577,6 +609,7 @@
 		return 0;
 	return pfn_valid(pte_pfn(*pte));
 }
+EXPORT_SYMBOL_GPL(kern_addr_valid);
 
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
--- linux-2.6.12/arch/x86_64/kernel/process.c.orig	2005-08-18 12:41:10.000000000 -0400
+++ linux-2.6.12/arch/x86_64/kernel/process.c	2005-08-18 14:23:59.000000000 -0400
@@ -314,6 +314,8 @@
 	show_trace(&regs->rsp);
 }
 
+EXPORT_SYMBOL_GPL(show_regs);
+
 /*
  * Free current thread data structures etc..
  */
--- linux-2.6.12/arch/x86_64/kernel/traps.c.orig	2005-08-18 12:40:02.000000000 -0400
+++ linux-2.6.12/arch/x86_64/kernel/traps.c	2005-08-18 14:23:59.000000000 -0400
@@ -364,8 +364,11 @@ void oops_end(unsigned long flags)
 	die_owner = -1;
 	bust_spinlocks(0);
 	spin_unlock_irqrestore(&die_lock, flags);
-	if (panic_on_oops)
+	if (panic_on_oops) {
+		if (netdump_func)
+			netdump_func = NULL;
 		panic("Oops");
+	}
 }
 
 void __die(const char * str, struct pt_regs * regs, long err)
@@ -399,6 +399,7 @@ void die(const char * str, struct pt_reg
 
 	handle_BUG(regs);
 	__die(str, regs, err);
+	try_crashdump(regs);
 	oops_end(flags);
 	do_exit(SIGSEGV); 
 }
--- linux-2.6.12/arch/ia64/mm/init.c.orig	2005-08-18 12:41:13.000000000 -0400
+++ linux-2.6.12/arch/ia64/mm/init.c	2005-08-18 14:23:59.000000000 -0400
@@ -258,12 +258,94 @@
 	}
 }
 
-int page_is_ram(unsigned long pagenr)
+struct curr_mem_request {
+	unsigned long requested;
+	unsigned long min_physaddr;
+	int found;
+};
+
+/*
+ *  Check whether a physical address fits within the memory descriptor
+ *  block sent from efi_mmap_walk(). If it fits, set found.
+ */
+static int
+verify_physaddr (unsigned long start, unsigned long end, void *arg)
+{
+	struct curr_mem_request *cr = arg;
+
+	start = __pa(start);
+	end = __pa(end);
+
+	if ((cr->requested >= start) && (cr->requested + PAGE_SIZE) <= end) {
+		cr->found = 1;
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * If physical page 'nr' is valid RAM then return 1.  Otherwise return 0.
+ */
+
+int
+page_is_ram (unsigned long pagenr)
+{
+	struct curr_mem_request cr;
+
+	if (!pfn_valid(pagenr))
+		return 0;
+
+	cr.requested = pagenr << PAGE_SHIFT;
+	cr.found = 0;
+
+	efi_memmap_walk(verify_physaddr, &cr);
+
+	return cr.found;
+}
+EXPORT_SYMBOL_GPL(page_is_ram);
+
+static int
+find_next (unsigned long start, unsigned long end, void *arg)
 {
-      //FIXME: implement w/efi walk
-      printk("page is ram is called!!!!!\n");	
-      return 1;
+	struct curr_mem_request *cr = (struct curr_mem_request *)arg;
+
+	start = __pa(start);
+	end = __pa(end);
+
+	if ((cr->requested >= start) && (cr->requested + PAGE_SIZE) <= end) {
+		cr->min_physaddr = cr->requested;
+		cr->found = 1;
+		return -1;
+	}
+	if ((cr->requested < start) && (start + PAGE_SIZE) <= end)
+		if (start < cr->min_physaddr) {
+			cr->min_physaddr = start;
+			cr->found = 1;
+		}
+
+	return 0;
+}
+
+unsigned long
+next_ram_page (unsigned long pagenr)
+{
+	struct curr_mem_request cr;
+
+	pagenr++;
+
+	cr.requested = pagenr << PAGE_SHIFT;
+	cr.found = 0;
+	cr.min_physaddr = ULONG_MAX;
+
+	efi_memmap_walk(find_next, &cr);
+
+	if (cr.found)
+		return cr.min_physaddr >> PAGE_SHIFT;
+	else
+		return ULONG_MAX;
 }
+EXPORT_SYMBOL_GPL(next_ram_page);
 
 /*
  * This installs a clean page in the kernel's page table.
--- linux-2.6.12/arch/ia64/mm/discontig.c.orig	2005-08-18 12:39:57.000000000 -0400
+++ linux-2.6.12/arch/ia64/mm/discontig.c	2005-08-18 14:23:59.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/acpi.h>
 #include <linux/efi.h>
 #include <linux/nodemask.h>
+#include <linux/module.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
 #include <asm/meminit.h>
@@ -556,6 +557,8 @@
 	printk("%d free buffer pages\n", nr_free_buffer_pages());
 }
 
+EXPORT_SYMBOL_GPL(show_mem);
+
 /**
  * call_pernode_memory - use SRAT to call callback functions with node info
  * @start: physical start of range
--- linux-2.6.12/arch/ia64/mm/contig.c.orig	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/arch/ia64/mm/contig.c	2005-08-18 14:23:59.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/efi.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
+#include <linux/module.h>
 
 #include <asm/meminit.h>
 #include <asm/pgalloc.h>
@@ -65,6 +66,8 @@
 		pgtable_quicklist_total_size());
 }
 
+EXPORT_SYMBOL_GPL(show_mem);
+
 /* physical address where the bootmem map is located */
 unsigned long bootmap_start;
 
--- linux-2.6.12/arch/ia64/kernel/process.c.orig	2005-08-18 12:41:05.000000000 -0400
+++ linux-2.6.12/arch/ia64/kernel/process.c	2005-08-18 14:25:30.000000000 -0400
@@ -41,6 +41,7 @@
 #include <asm/uaccess.h>
 #include <asm/unwind.h>
 #include <asm/user.h>
+#include <asm/diskdump.h>
 
 #include "entry.h"
 
@@ -154,6 +155,8 @@
 		show_stack(NULL, NULL);
 }
 
+EXPORT_SYMBOL_GPL(show_regs);
+
 void
 do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
 {
@@ -591,11 +594,13 @@
 }
 
 void
-do_copy_regs (struct unw_frame_info *info, void *arg)
+ia64_do_copy_regs (struct unw_frame_info *info, void *arg)
 {
 	do_copy_task_regs(current, info, arg);
 }
 
+EXPORT_SYMBOL_GPL(ia64_do_copy_regs);
+
 void
 do_dump_fpu (struct unw_frame_info *info, void *arg)
 {
@@ -608,7 +613,7 @@
 	struct unw_frame_info tcore_info;
 
 	if (current == task) {
-		unw_init_running(do_copy_regs, regs);
+		unw_init_running(ia64_do_copy_regs, regs);
 	} else {
 		memset(&tcore_info, 0, sizeof(tcore_info));
 		unw_init_from_blocked_task(&tcore_info, task);
@@ -620,7 +625,7 @@
 void
 ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
 {
-	unw_init_running(do_copy_regs, dst);
+	unw_init_running(ia64_do_copy_regs, dst);
 }
 
 int
@@ -821,3 +826,22 @@
 	machine_halt();
 }
 
+
+void
+ia64_freeze_cpu (struct unw_frame_info *info, void *arg)
+{
+	current->thread.ksp = (__u64)(info->sw) - 16;
+	for (;;) local_irq_disable();
+}
+
+EXPORT_SYMBOL_GPL(ia64_freeze_cpu);
+
+void
+ia64_start_dump (struct unw_frame_info *info, void *arg)
+{
+	struct dump_call_param *param = arg;
+
+	param->func(param->regs, info);
+}
+
+EXPORT_SYMBOL_GPL(ia64_start_dump);
--- linux-2.6.12/arch/ia64/kernel/traps.c.orig	2005-08-18 12:39:57.000000000 -0400
+++ linux-2.6.12/arch/ia64/kernel/traps.c	2005-08-18 14:23:59.000000000 -0400
@@ -108,6 +108,12 @@
   	} else
 		printk(KERN_ERR "Recursive die() failure, output suppressed\n");
 
+	try_crashdump(regs);
+	if (panic_on_oops) {
+		if (netdump_func)
+			netdump_func = NULL;
+		panic("Fatal exception");
+	}
 	bust_spinlocks(0);
 	die.lock_owner = -1;
 	spin_unlock_irq(&die.lock);
--- linux-2.6.12/arch/powerpc/mm/mem.c.orig	2005-08-18 12:41:13.000000000 -0400
+++ linux-2.6.12/arch/powerpc/mm/mem.c	2005-08-18 14:23:59.000000000 -0400
@@ -89,6 +89,34 @@
 }
 EXPORT_SYMBOL(page_is_ram);
 
+unsigned long next_ram_page(unsigned long pfn)
+{
+	int i;
+	unsigned long paddr, base;
+	unsigned long best_base = (ULONG_MAX << PAGE_SHIFT);
+
+	pfn++;
+	paddr = (pfn << PAGE_SHIFT);
+                                                                                
+	for (i=0; i < lmb.memory.cnt; i++) {
+#ifdef CONFIG_MSCHUNKS
+		base = lmb.memory.region[i].physbase;
+#else
+		base = lmb.memory.region[i].base;
+#endif
+		if ((paddr >= base)
+		    && (paddr < (base + lmb.memory.region[i].size)))
+			return (paddr >> PAGE_SHIFT);
+		if ((paddr < base) && (base < best_base))
+			best_base = base;
+	}
+	if (best_base < (ULONG_MAX << PAGE_SHIFT))
+		return (best_base >> PAGE_SHIFT);
+	else
+		return ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(next_ram_page);
+
 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 			      unsigned long size, pgprot_t vma_prot)
 {
@@ -216,6 +216,7 @@
 	printk("%ld pages shared\n", shared);
 	printk("%ld pages swap cached\n", cached);
 }
+EXPORT_SYMBOL_GPL(show_mem);
 
 /*
  * Initialize the bootmem system and give it all the memory we
--- linux-2.6.12/arch/powerpc/kernel/process.c.orig	2005-08-18 12:40:01.000000000 -0400
+++ linux-2.6.12/arch/powerpc/kernel/process.c	2005-08-18 14:23:59.000000000 -0400
@@ -444,6 +444,7 @@
 	if (!user_mode(regs))
 		show_instructions(regs);
 }
+EXPORT_SYMBOL_GPL(show_regs);
 
 void exit_thread(void)
 {
--- linux-2.6.12/arch/powerpc/kernel/traps.c.orig	2005-08-18 12:40:01.000000000 -0400
+++ linux-2.6.12/arch/powerpc/kernel/traps.c	2005-08-18 14:23:59.000000000 -0400
@@ -135,6 +135,7 @@
 		printk("\n");
 	print_modules();
 	show_regs(regs);
+	try_crashdump(regs);
 	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
 
@@ -142,6 +143,8 @@
 
 	if (panic_on_oops) {
 #ifdef CONFIG_PPC64
+		if (netdump_func)
+			netdump_func = NULL;
 		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
 		ssleep(5);
 #endif

--- linux-2.6.13/drivers/char/sysrq.c.orig
+++ linux-2.6.13/drivers/char/sysrq.c
@@ -95,12 +95,14 @@ static struct sysrq_key_op sysrq_unraw_o
 };
 #endif /* CONFIG_VT */
 
-#ifdef CONFIG_KEXEC
 /* crashdump sysrq handler */
 static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
 				struct tty_struct *tty)
 {
+#ifdef CONFIG_KEXEC
 	crash_kexec(pt_regs);
+#endif
+ 	*( (char *) 0) = 0;
 }
 static struct sysrq_key_op sysrq_crashdump_op = {
 	.handler	= sysrq_handle_crashdump,
@@ -108,7 +110,6 @@ static struct sysrq_key_op sysrq_crashdu
 	.action_msg	= "Trigger a crashdump",
 	.enable_mask	= SYSRQ_ENABLE_DUMP,
 };
-#endif
 
 /* reboot sysrq handler */
 static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,


linux-2.6-crashdump-reboot-exports.patch:
 linux-2.6.12/arch/i386/kernel/process.c         |    2 ++
 linux-2.6.12/arch/i386/kernel/reboot.c          |    4 ++++
 linux-2.6.12/arch/powerpc/kernel/setup-common.c |    2 ++
 linux-2.6.12/arch/powerpc/kernel/setup_64.c     |    2 ++
 linux-2.6.12/arch/s390/kernel/process.c         |    2 ++
 linux-2.6.12/arch/s390/kernel/setup.c           |    4 ++++
 linux-2.6.12/arch/x86_64/kernel/reboot.c        |    4 ++++
 linux-2.6.14/arch/ia64/kernel/process.c         |    2 ++
 8 files changed, 22 insertions(+)

--- NEW FILE linux-2.6-crashdump-reboot-exports.patch ---
--- linux-2.6.12/arch/s390/kernel/process.c.orig	2005-08-22 14:11:14.469588353 -0400
+++ linux-2.6.12/arch/s390/kernel/process.c	2005-08-22 14:11:31.717710903 -0400
@@ -158,6 +158,8 @@ void show_regs(struct pt_regs *regs)
 		show_trace(0,(unsigned long *) regs->gprs[15]);
 }
 
+EXPORT_SYMBOL(show_regs);
+
 extern void kernel_thread_starter(void);
 
 __asm__(".align 4\n"
--- linux-2.6.12/arch/s390/kernel/setup.c.orig	2005-08-22 14:11:53.530072038 -0400
+++ linux-2.6.12/arch/s390/kernel/setup.c	2005-08-22 14:12:09.611389274 -0400
@@ -299,12 +299,16 @@ void machine_restart(char *command)
 	_machine_restart(command);
 }
 
+EXPORT_SYMBOL(machine_restart);
+
 void machine_halt(void)
 {
 	console_unblank();
 	_machine_halt();
 }
 
+EXPORT_SYMBOL(machine_halt);
+
 void machine_power_off(void)
 {
 	console_unblank();
--- linux-2.6.14/arch/ia64/kernel/process.c~	2005-11-11 12:58:33.000000000 -0500
+++ linux-2.6.14/arch/ia64/kernel/process.c	2005-11-11 12:58:48.000000000 -0500
@@ -820,6 +820,7 @@ machine_restart (char *restart_cmd)
 	(void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
 	(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
 }
+EXPORT_SYMBOL(machine_restart);
 
 void
 machine_halt (void)
@@ -827,6 +828,7 @@ machine_halt (void)
 	(void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
 	cpu_halt();
 }
+EXPORT_SYMBOL(machine_halt);
 
 void
 machine_power_off (void)
--- linux-2.6.12/arch/powerpc/kernel/setup-common.c.orig	2005-08-22 14:09:24.318964809 -0400
+++ linux-2.6.12/arch/powerpc/kernel/setup-common.c	2005-08-22 14:09:43.133825875 -0400
@@ -695,6 +695,8 @@ void machine_restart(char *cmd)
 	while (1) ;
 }
 
+EXPORT_SYMBOL(machine_restart);
+
 void machine_power_off(void)
 {
 	machine_shutdown();
--- linux-2.6.12/arch/powerpc/kernel/setup_64.c.orig	2005-08-22 14:09:24.318964809 -0400
+++ linux-2.6.12/arch/powerpc/kernel/setup_64.c	2005-08-22 14:09:43.133825875 -0400
@@ -720,6 +722,8 @@ void machine_halt(void)
 	while (1) ;
 }
 
+EXPORT_SYMBOL(machine_halt);
+
 static int ppc64_panic_event(struct notifier_block *this,
                              unsigned long event, void *ptr)
 {
--- linux-2.6.12/arch/i386/kernel/process.c.orig	2005-08-22 14:06:18.768231301 -0400
+++ linux-2.6.12/arch/i386/kernel/process.c	2005-08-22 14:06:19.889041887 -0400
@@ -327,6 +327,8 @@ void show_regs(struct pt_regs * regs)
 	show_trace(NULL, &regs->esp);
 }
 
+EXPORT_SYMBOL(show_regs);
+
 /*
  * This gets run with %ebx containing the
  * function to call, and %edx containing
--- linux-2.6.12/arch/i386/kernel/reboot.c.orig	2005-08-22 14:06:57.191738225 -0400
+++ linux-2.6.12/arch/i386/kernel/reboot.c	2005-08-22 14:06:46.392563059 -0400
@@ -341,10 +341,14 @@ void machine_restart(char * __unused)
 	machine_emergency_restart();
 }
 
+EXPORT_SYMBOL(machine_restart);
+
 void machine_halt(void)
 {
 }
 
+EXPORT_SYMBOL(machine_halt);
+
 void machine_power_off(void)
 {
 	machine_shutdown();
--- linux-2.6.12/arch/x86_64/kernel/reboot.c.orig	2005-08-22 14:08:25.688786610 -0400
+++ linux-2.6.12/arch/x86_64/kernel/reboot.c	2005-08-22 14:08:17.449178506 -0400
@@ -147,10 +147,14 @@ void machine_restart(char * __unused)
 	machine_emergency_restart();
 }
 
+EXPORT_SYMBOL(machine_restart);
+
 void machine_halt(void)
 {
 }
 
+EXPORT_SYMBOL(machine_halt);
+
 void machine_power_off(void)
 {
 	if (!reboot_force) {

linux-2.6-debug-Wundef.patch:
 Makefile |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-debug-Wundef.patch ---
-Wundef

--- linux-2.6.11/Makefile~	2005-05-28 18:48:02.000000000 -0400
+++ linux-2.6.11/Makefile	2005-05-28 18:48:27.000000000 -0400
@@ -203,7 +203,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
 
 HOSTCC  	= gcc
 HOSTCXX  	= g++
-HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -Wundef
 HOSTCXXFLAGS	= -O2
 
 # 	Decide whether to build built-in, modular, or both.

linux-2.6-debug-disable-builtins.patch:
 Makefile |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-debug-disable-builtins.patch ---
Disable built-ins and also more m32 work

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/arch/i386/Makefile linux-10000/arch/i386/Makefile
--- linux-3022/arch/i386/Makefile
+++ linux-10000/arch/i386/Makefile
@@ -22,7 +22,7 @@ OBJCOPYFLAGS	:= -O binary -R .note -R .c
 LDFLAGS_vmlinux :=
 CHECKFLAGS	+= -D__i386__
 
-CFLAGS += -pipe -msoft-float
+CFLAGS += -pipe -msoft-float -fno-builtin-sprintf -fno-builtin-log2 -fno-builtin-puts 
 
 # prevent gcc from keeping the stack 16 byte aligned
 CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)


linux-2.6-debug-dual-line-backtrace.patch:
 traps.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-debug-dual-line-backtrace.patch ---
--- linux-2.6.14/arch/i386/kernel/traps.c~	2005-12-01 04:25:36.000000000 -0500
+++ linux-2.6.14/arch/i386/kernel/traps.c	2005-12-01 04:36:19.000000000 -0500
@@ -116,6 +116,7 @@ static inline unsigned long print_contex
 				unsigned long *stack, unsigned long ebp)
 {
 	unsigned long addr;
+	char space=0;
 
 #ifdef	CONFIG_FRAME_POINTER
 	while (valid_stack_ptr(tinfo, (void *)ebp)) {
@@ -131,9 +132,17 @@ static inline unsigned long print_contex
 		if (__kernel_text_address(addr)) {
 			printk(" [<%08lx>]", addr);
 			print_symbol(" %s", addr);
-			printk("\n");
+			if (space == 0) {
+				printk("    ");
+				space = 1;
+			} else {
+				printk("\n");
+				space = 0;
+			}
 		}
 	}
+	if (space==1)
+		printk("\n");
 #endif
 	return ebp;
 }

linux-2.6-debug-list_head.patch:
 list.h |    4 ++++
 1 files changed, 4 insertions(+)

--- NEW FILE linux-2.6-debug-list_head.patch ---
list_head debugging from -mm

--- linux-2.6.12/include/linux/list.h~	2005-08-08 15:34:50.000000000 -0400
+++ linux-2.6.12/include/linux/list.h	2005-08-08 15:35:22.000000000 -0400
@@ -5,7 +5,9 @@
 
 #include <linux/stddef.h>
 #include <linux/prefetch.h>
+#include <linux/kernel.h>
 #include <asm/system.h>
+#include <asm/bug.h>
 
 /*
  * These are non-NULL pointers that will result in page faults
@@ -160,6 +162,8 @@ static inline void __list_del(struct lis
  */
 static inline void list_del(struct list_head *entry)
 {
+	BUG_ON(entry->prev->next != entry);
+	BUG_ON(entry->next->prev != entry);
 	__list_del(entry->prev, entry->next);
 	entry->next = LIST_POISON1;
 	entry->prev = LIST_POISON2;

linux-2.6-debug-no-quiet.patch:
 main.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-debug-no-quiet.patch ---
--- linux-2.6.14/init/main.c~	2005-12-02 01:23:31.000000000 -0500
+++ linux-2.6.14/init/main.c	2005-12-02 01:23:51.000000000 -0500
@@ -210,7 +210,7 @@ static int __init quiet_kernel(char *str
 {
 	if (*str)
 		return 0;
-	console_loglevel = 4;
+	console_loglevel = 10;
 	return 1;
 }
 

linux-2.6-debug-panic-stackdump.patch:
 panic.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6-debug-panic-stackdump.patch ---
--- linux-2.6.12/kernel/panic.c~	2005-06-27 01:31:30.000000000 -0400
+++ linux-2.6.12/kernel/panic.c	2005-06-27 01:31:40.000000000 -0400
@@ -76,6 +76,7 @@ NORET_TYPE void panic(const char * fmt, 
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 	printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
+ 	dump_stack();
 	bust_spinlocks(0);
 
 	/*

linux-2.6-debug-reference-discarded-return-result.patch:
 reference_discarded.pl |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-debug-reference-discarded-return-result.patch ---
?

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/scripts/reference_discarded.pl linux-10000/scripts/reference_discarded.pl
--- linux-3022/scripts/reference_discarded.pl
+++ linux-10000/scripts/reference_discarded.pl
@@ -107,4 +108,4 @@ foreach $object (keys(%object)) {
 }
 # printf("Done\n");
 
-exit(0);
+exit($errorcount);

linux-2.6-debug-singlebiterror.patch:
 slab.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+)

--- NEW FILE linux-2.6-debug-singlebiterror.patch ---
--- linux-2.6.11/mm/slab.c~	2005-05-01 00:51:59.000000000 -0400
+++ linux-2.6.11/mm/slab.c	2005-05-01 01:19:38.000000000 -0400
@@ -1004,8 +1004,12 @@ static void poison_obj(kmem_cache_t *cac
 static void dump_line(char *data, int offset, int limit)
 {
 	int i;
+	unsigned char total=0;
+
 	printk(KERN_ERR "%03x:", offset);
 	for (i=0;i<limit;i++) {
+		if (data[offset+i] != POISON_FREE)
+			total += data[offset+i];
 		if (check_tainted() == 0)
 			printk(" %02x", (unsigned char)data[offset+i]);
 		else {
@@ -1019,6 +1023,18 @@ static void dump_line(char *data, int of
 		}
 	}
 	printk("\n");
+	switch (total) {
+		case 0x36:
+		case 0x6a:
+		case 0x6f:
+		case 0x81:
+		case 0xac:
+		case 0xd3:
+		case 0xd5:
+		case 0xea:
+			printk (KERN_ERR "Single bit error detected. Possibly bad RAM. Run memtest86.\n");
+			return;
+	}
 }
 #endif
 

linux-2.6-debug-slab-backtrace.patch:
 slab.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6-debug-slab-backtrace.patch ---
Sometimes it's possible that the debug info gets disabled
due to alignment issues. If we then get a corruption we
have very few clues wtf happened.

--- linux-2.6.11/mm/slab.c~	2005-04-20 03:07:42.000000000 -0400
+++ linux-2.6.11/mm/slab.c	2005-04-20 03:07:48.000000000 -0400
@@ -1064,6 +1064,7 @@ static void check_poison_obj(kmem_cache_
 				printk(KERN_ERR "Slab corruption: (%s) start=%p, len=%d\n",
 						print_tainted(), realobj, size);
 				print_objinfo(cachep, objp, 0);
+				dump_stack();
 			}
 			/* Hexdump the affected line */
 			i = (i/16)*16;

linux-2.6-debug-sleep-in-irq-warning.patch:
 delay.h |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

--- NEW FILE linux-2.6-debug-sleep-in-irq-warning.patch ---
warn if we sleep in an irq for a long time.

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/include/linux/delay.h linux-10000/include/linux/delay.h
--- linux-3022/include/linux/delay.h
+++ linux-10000/include/linux/delay.h
@@ -10,7 +10,7 @@
 extern unsigned long loops_per_jiffy;
 
 #include <asm/delay.h>
-
+#include <linux/hardirq.h>
 /*
  * Using udelay() for intervals greater than a few milliseconds can
  * risk overflow for high loops_per_jiffy (high bogomips) machines. The
@@ -25,14 +25,13 @@ extern unsigned long loops_per_jiffy;
 #define MAX_UDELAY_MS	5
 #endif
 
-#ifdef notdef
-#define mdelay(n) (\
-	{unsigned long __ms=(n); while (__ms--) udelay(1000);})
-#else
-#define mdelay(n) (\
-	(__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \
-	({unsigned long __ms=(n); while (__ms--) udelay(1000);}))
-#endif
+#define mdelay(n) (					\
+	{						\
+		static int warned=0; 			\
+		unsigned long __ms=(n); 		\
+		WARN_ON(in_irq() && !(warned++)); 	\
+		while (__ms--) udelay(1000);		\
+	})
 
 #ifndef ndelay
 #define ndelay(x)	udelay(((x)+999)/1000)

linux-2.6-debug-spinlock-panic.patch:
 spinlock_debug.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-debug-spinlock-panic.patch ---
By default, change the spinlock debugging to panic instead of printk.
This catches a lot of problems that previously would go unreported.
The only problem with this is that if we hit this in the installer kernel,
the user can't install the release. As a worse-case scenario, we have
a 'dontpanic' boot argument. Douglas Adams would be proud.

--- linux-2.6.13/lib/spinlock_debug.c~	2005-09-12 20:14:31.000000000 -0400
+++ linux-2.6.13/lib/spinlock_debug.c	2005-09-12 20:15:56.000000000 -0400
@@ -11,6 +11,16 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 
+int nopanic;
+static int __init nopanic_setup(char *str)
+{
+	nopanic = 1;
+	return 1;
+}
+EXPORT_SYMBOL(nopanic);
+__setup("dontpanic", nopanic_setup);
+
+
 static void spin_bug(spinlock_t *lock, const char *msg)
 {
 	static long print_once = 1;
@@ -31,7 +41,10 @@ static void spin_bug(spinlock_t *lock, c
 		/*
 		 * We cannot continue on SMP:
 		 */
-//		panic("bad locking");
+		if (nopanic)
+			printk("bad locking\n");
+		else
+			panic("bad locking");
 #endif
 	}
 }

linux-2.6-debug-spinlock-taint.patch:
 spinlock_debug.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

--- NEW FILE linux-2.6-debug-spinlock-taint.patch ---
Print info about tainting in the spinlock debug printks.

--- linux-2.6.13/lib/spinlock_debug.c~	2005-09-12 20:10:31.000000000 -0400
+++ linux-2.6.13/lib/spinlock_debug.c	2005-09-12 20:13:57.000000000 -0400
@@ -19,8 +19,8 @@ static void spin_bug(spinlock_t *lock, c
 	if (xchg(&print_once, 0)) {
 		if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
 			owner = lock->owner;
-		printk("BUG: spinlock %s on CPU#%d, %s/%d\n",
-			msg, smp_processor_id(), current->comm, current->pid);
+		printk("BUG: spinlock %s on CPU#%d, %s/%d (%s)\n",
+			msg, smp_processor_id(), current->comm, current->pid, print_tainted());
 		printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n",
 			lock, lock->magic,
 			owner ? owner->comm : "<none>",
@@ -77,9 +77,9 @@ static void __spin_lock_debug(spinlock_t
 		/* lockup suspected: */
 		if (print_once) {
 			print_once = 0;
-			printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n",
+			printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p (%s)\n",
 				smp_processor_id(), current->comm, current->pid,
-					lock);
+					lock, print_tainted());
 			dump_stack();
 		}
 	}
@@ -119,8 +119,8 @@ static void rwlock_bug(rwlock_t *lock, c
 	static long print_once = 1;
 
 	if (xchg(&print_once, 0)) {
-		printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg,
-			smp_processor_id(), current->comm, current->pid, lock);
+		printk("BUG: rwlock %s on CPU#%d, %s/%d, %p (%s)\n", msg,
+			smp_processor_id(), current->comm, current->pid, lock, print_tainted());
 		dump_stack();
 #ifdef CONFIG_SMP
 		/*
@@ -147,9 +147,9 @@ static void __read_lock_debug(rwlock_t *
 		/* lockup suspected: */
 		if (print_once) {
 			print_once = 0;
-			printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n",
+			printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p (%s)\n",
 				smp_processor_id(), current->comm, current->pid,
-					lock);
+					lock, print_tainted());
 			dump_stack();
 		}
 	}
@@ -219,9 +219,9 @@ static void __write_lock_debug(rwlock_t 
 		/* lockup suspected: */
 		if (print_once) {
 			print_once = 0;
-			printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n",
+			printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p (%s)\n",
 				smp_processor_id(), current->comm, current->pid,
-					lock);
+					lock, print_tainted());
 			dump_stack();
 		}
 	}

linux-2.6-debug-sysfs-crash-debugging.patch:
 arch/i386/kernel/traps.c |    5 +++++
 fs/sysfs/file.c          |    8 ++++++++
 2 files changed, 13 insertions(+)

--- NEW FILE linux-2.6-debug-sysfs-crash-debugging.patch ---

From: Andrew Morton <akpm at osdl.org>

Display the most-recently-opened sysfs file's name when oopsing.

From: Adrian Bunk <bunk at stusta.de>

  Build fix

Signed-off-by: Adrian Bunk <bunk at stusta.de>
Signed-off-by: Andrew Morton <akpm at osdl.org>
---

 arch/i386/kernel/traps.c |    5 +++++
 fs/sysfs/file.c          |    8 ++++++++
 2 files changed, 13 insertions(+)

diff -puN fs/sysfs/file.c~sysfs-crash-debugging fs/sysfs/file.c
--- devel/fs/sysfs/file.c~sysfs-crash-debugging	2005-11-22 22:31:16.000000000 -0800
+++ devel-akpm/fs/sysfs/file.c	2005-11-22 22:31:16.000000000 -0800
@@ -6,6 +6,8 @@
 #include <linux/fsnotify.h>
 #include <linux/kobject.h>
 #include <linux/namei.h>
+#include <linux/limits.h>
+
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 
@@ -324,8 +326,14 @@ static int check_perm(struct inode * ino
 	return error;
 }
 
+char last_sysfs_file[PATH_MAX];
+
 static int sysfs_open_file(struct inode * inode, struct file * filp)
 {
+	char *p = d_path(filp->f_dentry, sysfs_mount, last_sysfs_file,
+			sizeof(last_sysfs_file));
+	if (p)
+		memmove(last_sysfs_file, p, strlen(p) + 1);
 	return check_perm(inode,filp);
 }
 
diff -puN arch/i386/kernel/traps.c~sysfs-crash-debugging arch/i386/kernel/traps.c
--- devel/arch/i386/kernel/traps.c~sysfs-crash-debugging	2005-11-22 22:31:16.000000000 -0800
+++ devel-akpm/arch/i386/kernel/traps.c	2005-11-22 22:31:16.000000000 -0800
@@ -95,6 +95,8 @@ static int kstack_depth_to_print = 24;
 struct notifier_block *i386die_chain;
 static DEFINE_SPINLOCK(die_notifier_lock);
 
+extern char last_sysfs_file[];
+
 int register_die_notifier(struct notifier_block *nb)
 {
 	int err = 0;
@@ -346,6 +346,9 @@ void die(const char * str, struct pt_reg
 #endif
 		if (nl)
 			printk("\n");
+#ifdef CONFIG_SYSFS
+		printk(KERN_ALERT "last sysfs file: %s\n", last_sysfs_file);
+#endif
 	notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
 		show_registers(regs);
 		try_crashdump(regs);

linux-2.6-debug-taint-check.patch:
 linux-2.6.11/arch/i386/kernel/traps.c |    5 ++++-
 linux-2.6.11/include/linux/kernel.h   |    1 +
 linux-2.6.11/kernel/panic.c           |    7 +++++++
 linux-2.6.11/mm/slab.c                |   12 +++++++++++-
 linux-2.6.13/arch/i386/kernel/traps.c |    7 ++++---
 5 files changed, 27 insertions(+), 5 deletions(-)

--- NEW FILE linux-2.6-debug-taint-check.patch ---
--- linux-2.6.11/kernel/panic.c~	2005-04-20 03:48:57.000000000 -0400
+++ linux-2.6.11/kernel/panic.c	2005-04-20 03:49:28.000000000 -0400
@@ -159,3 +159,10 @@ void add_taint(unsigned flag)
 	tainted |= flag;
 }
 EXPORT_SYMBOL(add_taint);
+
+int check_tainted(void)
+{
+	return tainted;
+}
+EXPORT_SYMBOL_GPL(check_tainted);
+
--- linux-2.6.11/include/linux/kernel.h~	2005-04-20 03:49:49.000000000 -0400
+++ linux-2.6.11/include/linux/kernel.h	2005-04-20 03:49:56.000000000 -0400
@@ -156,6 +156,7 @@ extern int panic_on_oops;
 extern int tainted;
 extern const char *print_tainted(void);
 extern void add_taint(unsigned);
+extern int check_tainted(void);
 
 #define crashdump_mode()       unlikely(netdump_mode || diskdump_mode)
 
--- linux-2.6.11/arch/i386/kernel/traps.c~	2005-04-20 03:57:00.000000000 -0400
+++ linux-2.6.11/arch/i386/kernel/traps.c	2005-04-20 03:58:23.000000000 -0400
@@ -182,7 +182,10 @@ void show_stack(struct task_struct *task
 			break;
 		if (i && ((i % 8) == 0))
 			printk("\n       ");
-		printk("%08lx ", *stack++);
+		if ((check_tainted() != 0) && (i==0))
+			printk("badc0ded ");
+		else
+			printk("%08lx ", *stack++);
 	}
 	printk("\nCall Trace:\n");
 	show_trace(task, esp);
--- linux-2.6.11/mm/slab.c~	2005-04-21 00:48:06.000000000 -0400
+++ linux-2.6.11/mm/slab.c	2005-04-21 00:57:00.000000000 -0400
@@ -1006,7 +1006,17 @@ static void dump_line(char *data, int of
 	int i;
 	printk(KERN_ERR "%03x:", offset);
 	for (i=0;i<limit;i++) {
-		printk(" %02x", (unsigned char)data[offset+i]);
+		if (check_tainted() == 0)
+			printk(" %02x", (unsigned char)data[offset+i]);
+		else {
+			switch (i) {
+			case 0:	printk(" f3 3d");
+					break;
+			case 1: break;
+			default:
+				printk(" %02x", (unsigned char)data[offset+i]);
+			}
+		}
 	}
 	printk("\n");
 }
--- linux-2.6.13/arch/i386/kernel/traps.c~	2005-09-15 13:55:11.000000000 -0400
+++ linux-2.6.13/arch/i386/kernel/traps.c	2005-09-15 13:57:32.000000000 -0400
@@ -184,10 +184,11 @@ void show_stack(struct task_struct *task
 			break;
 		if (i && ((i % 8) == 0))
 			printk("\n       ");
-		if ((check_tainted() != 0) && (i==0))
+		if ((check_tainted() != 0) && (i==0)) {
 			printk("badc0ded ");
-		else
-			printk("%08lx ", *stack++);
+			i++;
+		}
+		printk("%08lx ", *stack++);
 	}
 	printk("\nCall Trace:\n");
 	show_trace(task, esp);

linux-2.6-debug-taint-proprietary-helpers.patch:
 module.c |    5 +++++
 1 files changed, 5 insertions(+)

--- NEW FILE linux-2.6-debug-taint-proprietary-helpers.patch ---

Kernels that have had Windows drivers loaded into them are
undebuggable.  As we're not interested in those bug reports,
make sure any oopses are marked accordingly.

Signed-off-by: Dave Jones <davej at redhat.com>

--- linux-2.6.14/kernel/module.c~	2005-11-29 16:44:00.000000000 -0500
+++ linux-2.6.14/kernel/module.c	2005-11-29 17:03:55.000000000 -0500
@@ -1723,6 +1723,11 @@ static struct module *load_module(void _
 	/* Set up license info based on the info section */
 	set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
+	if (strcmp(mod->name, "ndiswrapper") == 0)
+		add_taint(TAINT_PROPRIETARY_MODULE);
+	if (strcmp(mod->name, "driverloader") == 0)
+		add_taint(TAINT_PROPRIETARY_MODULE);
+
 #ifdef CONFIG_MODULE_UNLOAD
 	/* Set up MODINFO_ATTR fields */
 	setup_modinfo(mod, sechdrs, infoindex);

linux-2.6-debug-taint-vm.patch:
 linux-2.6.11/include/asm-generic/bug.h |    8 ++++++--
 linux-2.6.14/mm/page_alloc.c           |    4 ++--
 linux-2000/kernel/panic.c              |    1 +
 linux-2000/mm/slab.c                   |    4 ++--
 4 files changed, 11 insertions(+), 6 deletions(-)

--- NEW FILE linux-2.6-debug-taint-vm.patch ---
--- linux-2.6.11/include/asm-generic/bug.h~	2005-05-09 18:00:44.000000000 -0400
+++ linux-2.6.11/include/asm-generic/bug.h	2005-05-09 18:01:23.000000000 -0400
@@ -4,10 +4,14 @@
 #include <linux/compiler.h>
 #include <linux/config.h>
 
+#ifndef __ASSEMBLY__
+extern const char *print_tainted(void);
+#endif
+
 #ifdef CONFIG_BUG
 #ifndef HAVE_ARCH_BUG
 #define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	printk("kernel BUG at %s:%d! (%s)\n", __FILE__, __LINE__, print_tainted()); \
 	panic("BUG!"); \
 } while (0)
 #endif
@@ -25,7 +29,7 @@
 #ifndef HAVE_ARCH_WARN_ON
 #define WARN_ON(condition) do { \
 	if (unlikely((condition)!=0)) { \
-		printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
+		printk("Badness in %s at %s:%d (%s)\n", __FUNCTION__, __FILE__, __LINE__, print_tainted()); \
 		dump_stack(); \
 	} \
 } while (0)
diff -urNp --exclude-from=/home/davej/.exclude linux-1740/kernel/panic.c linux-2000/kernel/panic.c
--- linux-1740/kernel/panic.c
+++ linux-2000/kernel/panic.c
@@ -151,6 +151,7 @@ const char *print_tainted(void)
 		snprintf(buf, sizeof(buf), "Not tainted");
 	return(buf);
 }
+EXPORT_SYMBOL(print_tainted);
 
 void add_taint(unsigned flag)
 {
--- linux-2.6.14/mm/page_alloc.c~	2005-11-15 12:09:41.000000000 -0500
+++ linux-2.6.14/mm/page_alloc.c	2005-11-15 12:10:01.000000000 -0500
@@ -126,9 +126,9 @@ static void bad_page(const char *functio
 {
 	printk(KERN_EMERG "Bad page state at %s (in process '%s', page %p)\n",
 		function, current->comm, page);
-	printk(KERN_EMERG "flags:0x%0*lx mapping:%p mapcount:%d count:%d\n",
+	printk(KERN_EMERG "flags:0x%0*lx mapping:%p mapcount:%d count:%d (%s)\n",
 		(int)(2*sizeof(unsigned long)), (unsigned long)page->flags,
-		page->mapping, page_mapcount(page), page_count(page));
+		page->mapping, page_mapcount(page), page_count(page), print_tainted());
 	printk(KERN_EMERG "Backtrace:\n");
 	dump_stack();
 	printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n");
diff -urNp --exclude-from=/home/davej/.exclude linux-1740/mm/slab.c linux-2000/mm/slab.c
--- linux-1740/mm/slab.c
+++ linux-2000/mm/slab.c
@@ -1053,8 +1053,8 @@ static void check_poison_obj(kmem_cache_
 			/* Mismatch ! */
 			/* Print header */
 			if (lines == 0) {
-				printk(KERN_ERR "Slab corruption: start=%p, len=%d\n",
-						realobj, size);
+				printk(KERN_ERR "Slab corruption: (%s) start=%p, len=%d\n",
+						print_tainted(), realobj, size);
 				print_objinfo(cachep, objp, 0);
 			}
 			/* Hexdump the affected line */

linux-2.6-default-clocksource-tsc.patch:
 timer.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-default-clocksource-tsc.patch ---
--- linux-2.6.13/arch/i386/kernel/timers/timer.c~	2005-10-16 18:38:56.000000000 -0400
+++ linux-2.6.13/arch/i386/kernel/timers/timer.c	2005-10-16 18:39:04.000000000 -0400
@@ -19,10 +19,10 @@ static struct init_timer_opts* __initdat
 #ifdef CONFIG_HPET_TIMER
 	&timer_hpet_init,
 #endif
+	&timer_tsc_init,
 #ifdef CONFIG_X86_PM_TIMER
 	&timer_pmtmr_init,
 #endif
-	&timer_tsc_init,
 	&timer_pit_init,
 	NULL,
 };

linux-2.6-devmem-xen.patch:
 linux-2.6.11/include/asm-xen/asm-i386/io.h  |   11 +++++++++++
 linux-2.6.8/include/asm-xen/asm-i386/page.h |    2 ++
 2 files changed, 13 insertions(+)

--- NEW FILE linux-2.6-devmem-xen.patch ---
--- linux-2.6.8/include/asm-xen/asm-i386/page.h.devmem	2004-10-15 15:24:02.000000000 -0400
+++ linux-2.6.8/include/asm-xen/asm-i386/page.h	2004-10-15 15:24:31.000000000 -0400
@@ -207,6 +207,8 @@ static __inline__ int get_order(unsigned
 #define virt_to_machine(_a)	(phys_to_machine(__pa(_a)))
 #define machine_to_virt(_m)	(__va(machine_to_phys(_m)))
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _I386_PAGE_H */
--- linux-2.6.11/include/asm-xen/asm-i386/io.h.rc4	2005-05-16 16:30:29.000000000 -0400
+++ linux-2.6.11/include/asm-xen/asm-i386/io.h	2005-05-16 16:31:41.000000000 -0400
@@ -50,6 +50,17 @@
 #include <linux/vmalloc.h>
 #include <asm/fixmap.h>
 
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p)    __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)   p
+
 /**
  *	virt_to_phys	-	map virtual addresses to physical
  *	@address: address to remap

linux-2.6-devmem.patch:
 arch/powerpc/mm/mem.c                   |   14 +++
 linux-1050/arch/i386/mm/init.c          |   19 ++++
 linux-1050/arch/ia64/mm/init.c          |    7 +
 linux-1050/arch/s390/mm/init.c          |    5 +
 linux-1050/arch/x86_64/mm/init.c        |   20 ++++
 linux-1050/drivers/char/mem.c           |  146 ++++----------------------------
 linux-1050/fs/proc/kcore.c              |    2 
 linux-1050/include/asm-alpha/page.h     |    1 
 linux-1050/include/asm-arm/page.h       |    2 
 linux-1050/include/asm-arm26/page.h     |    2 
 linux-1050/include/asm-cris/page.h      |    2 
 linux-1050/include/asm-h8300/page.h     |    2 
 linux-1050/include/asm-i386/page.h      |    4 
 linux-1050/include/asm-ia64/page.h      |    2 
 linux-1050/include/asm-m68k/page.h      |    2 
 linux-1050/include/asm-m68knommu/page.h |    2 
 linux-1050/include/asm-mips/page.h      |    2 
 linux-1050/include/asm-parisc/page.h    |    2 
 linux-1050/include/asm-ppc/page.h       |    2 
 linux-1050/include/asm-s390/page.h      |    2 
 linux-1050/include/asm-sh/page.h        |    2 
 linux-1050/include/asm-sh64/page.h      |    2 
 linux-1050/include/asm-sparc/page.h     |    2 
 linux-1050/include/asm-sparc64/page.h   |    2 
 linux-1050/include/asm-um/page.h        |    1 
 linux-1050/include/asm-v850/page.h      |    2 
 linux-1050/include/asm-x86_64/page.h    |    4 
 linux-2.6.13/arch/x86_64/mm/init.c      |   22 ++++
 linux-2.6.14/include/asm-powerpc/page.h |    2 
 29 files changed, 154 insertions(+), 125 deletions(-)

--- NEW FILE linux-2.6-devmem.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/arch/i386/mm/init.c linux-1050/arch/i386/mm/init.c
--- linux-1020/arch/i386/mm/init.c
+++ linux-1050/arch/i386/mm/init.c
@@ -229,6 +229,25 @@ static inline int page_is_ram(unsigned l
 	return 0;
 }
 
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
+ * valid. The argument is a physical page number.
+ *
+ *
+ * On x86, access has to be given to the first megabyte of ram because that area
+ * contains bios code and data regions used by X and dosemu and similar apps.
+ * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+ * mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
+   if (pagenr <= 256)
+       return 1;
+   if (!page_is_ram(pagenr))
+       return 1;
+   return 0;
+}
+
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/arch/ia64/mm/init.c linux-1050/arch/ia64/mm/init.c
--- linux-1020/arch/ia64/mm/init.c
+++ linux-1050/arch/ia64/mm/init.c
@@ -230,6 +230,13 @@ free_initrd_mem (unsigned long start, un
 	}
 }
 
+int page_is_ram(unsigned long pagenr)
+{
+      //FIXME: implement w/efi walk
+      printk("page is ram is called!!!!!\n");	
+      return 1;
+}
+
 /*
  * This installs a clean page in the kernel's page table.
  */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/arch/ppc64/mm/init.c linux-1050/arch/ppc64/mm/init.c
--- linux-1020/arch/powerpc/mm/mem.c
+++ linux-1050/arch/powerpc/mm/mem.c
@@ -46,6 +46,7 @@
 #include <asm/prom.h>
 #include <asm/lmb.h>
 #include <asm/sections.h>
+#include <asm/rtas.h>
 #include <asm/vdso.h>
 
 #include "mmu_decl.h"
@@ -722,6 +722,19 @@ void __init mem_init(void)
 	max_mapnr = num_physpages;
 	totalram_pages += free_all_bootmem();
 #endif
+
+#ifdef CONFIG_PPC_PSERIES
+	/* Mark the RTAS pages as PG_reserved so userspace can mmap them */
+	if (rtas_rmo_buf) {
+		unsigned long pfn, start_pfn, end_pfn;
+
+		start_pfn = rtas_rmo_buf >> PAGE_SHIFT;
+		end_pfn = (rtas_rmo_buf + RTAS_RMOBUF_MAX) >>  PAGE_SHIFT;
+		for (pfn = start_pfn; pfn < end_pfn; pfn++)
+			SetPageReserved(pfn_to_page(pfn));
+	}
+#endif
+
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
 			page = pgdat->node_mem_map + i;
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/arch/s390/mm/init.c linux-1050/arch/s390/mm/init.c
--- linux-1020/arch/s390/mm/init.c
+++ linux-1050/arch/s390/mm/init.c
@@ -253,6 +253,11 @@ void __init paging_init(void)
 }
 #endif /* CONFIG_ARCH_S390X */
 
+int page_is_ram (unsigned long pagenr)
+{
+	return pagenr < max_mapnr;
+}
+
 void __init mem_init(void)
 {
 	unsigned long codesize, reservedpages, datasize, initsize;
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/arch/x86_64/mm/init.c linux-1050/arch/x86_64/mm/init.c
--- linux-1020/arch/x86_64/mm/init.c
+++ linux-1050/arch/x86_64/mm/init.c
@@ -397,6 +397,26 @@ static inline int page_is_ram (unsigned 
 
 extern int swiotlb_force;
 
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
+ * valid. The argument is a physical page number.
+ *
+ *
+ * On x86-64, access has to be given to the first megabyte of ram because that area
+ * contains bios code and data regions used by X and dosemu and similar apps.
+ * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+ * mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
+	if (pagenr <= 256)
+		return 1;
+	if (!page_is_ram(pagenr))
+		return 1;
+	return 0;
+}
+
+
 static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
 			 kcore_vsyscall;
 
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/drivers/char/mem.c linux-1050/drivers/char/mem.c
--- linux-1020/drivers/char/mem.c
+++ linux-1050/drivers/char/mem.c
@@ -111,6 +111,22 @@ static inline int valid_phys_addr_range(
 }
 #endif
 
+static inline int range_is_allowed(unsigned long from, unsigned long to)
+{
+	unsigned long cursor;
+
+	cursor = from >> PAGE_SHIFT;
+	while ((cursor << PAGE_SHIFT) < to) {
+		if (!devmem_is_allowed(cursor)) {
+			printk ("Program %s tried to read /dev/mem between %lx->%lx.\n",
+					current->comm, from, to);
+			return 0;
+		}
+		cursor++;
+	}
+	return 1;
+}
+
 /*
  * This funcion reads the *physical* memory. The f_pos points directly to the 
  * memory location. 
@@ -160,6 +176,8 @@ static ssize_t read_mem(struct file * fi
 		 */
 		ptr = xlate_dev_mem_ptr(p);
 
+		if (!range_is_allowed(p, p+count))
+			return -EPERM;
 		if (copy_to_user(buf, ptr, sz))
 			return -EFAULT;
 		buf += sz;
@@ -217,6 +235,8 @@ static ssize_t write_mem(struct file * f
 		 */
 		ptr = xlate_dev_mem_ptr(p);
 
+		if (!range_is_allowed(ptr, ptr+sz))
+			return -EPERM;
 		copied = copy_from_user(ptr, buf, sz);
 		if (copied) {
 			ssize_t ret;
@@ -270,6 +290,8 @@ static ssize_t read_kmem(struct file *fi
 	ssize_t read, virtr, sz;
 	char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
 
+	return -EPERM;
+
 	read = 0;
 	virtr = 0;
 	if (p < (unsigned long) high_memory) {
@@ -345,128 +367,6 @@ static ssize_t read_kmem(struct file *fi
 }
 
 
-static inline ssize_t
-do_write_kmem(void *p, unsigned long realp, const char __user * buf,
-	      size_t count, loff_t *ppos)
-{
-	ssize_t written, sz;
-	unsigned long copied;
-
-	written = 0;
-#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
-	/* we don't have page 0 mapped on sparc and m68k.. */
-	if (realp < PAGE_SIZE) {
-		unsigned long sz = PAGE_SIZE - realp;
-		if (sz > count)
-			sz = count;
-		/* Hmm. Do something? */
-		buf += sz;
-		p += sz;
-		realp += sz;
-		count -= sz;
-		written += sz;
-	}
-#endif
-
-	while (count > 0) {
-		char *ptr;
-		/*
-		 * Handle first page in case it's not aligned
-		 */
-		if (-realp & (PAGE_SIZE - 1))
-			sz = -realp & (PAGE_SIZE - 1);
-		else
-			sz = PAGE_SIZE;
-
-		sz = min_t(unsigned long, sz, count);
-
-		/*
-		 * On ia64 if a page has been mapped somewhere as
-		 * uncached, then it must also be accessed uncached
-		 * by the kernel or data corruption may occur
-		 */
-		ptr = xlate_dev_kmem_ptr(p);
-
-		copied = copy_from_user(ptr, buf, sz);
-		if (copied) {
-			ssize_t ret;
-
-			ret = written + (sz - copied);
-			if (ret)
-				return ret;
-			return -EFAULT;
-		}
-		buf += sz;
-		p += sz;
-		realp += sz;
-		count -= sz;
-		written += sz;
-	}
-
-	*ppos += written;
-	return written;
-}
-
-
-/*
- * This function writes to the *virtual* memory as seen by the kernel.
- */
-static ssize_t write_kmem(struct file * file, const char __user * buf, 
-			  size_t count, loff_t *ppos)
-{
-	unsigned long p = *ppos;
-	ssize_t wrote = 0;
-	ssize_t virtr = 0;
-	ssize_t written;
-	char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
-
-	if (p < (unsigned long) high_memory) {
-
-		wrote = count;
-		if (count > (unsigned long) high_memory - p)
-			wrote = (unsigned long) high_memory - p;
-
-		written = do_write_kmem((void*)p, p, buf, wrote, ppos);
-		if (written != wrote)
-			return written;
-		wrote = written;
-		p += wrote;
-		buf += wrote;
-		count -= wrote;
-	}
-
-	if (count > 0) {
-		kbuf = (char *)__get_free_page(GFP_KERNEL);
-		if (!kbuf)
-			return wrote ? wrote : -ENOMEM;
-		while (count > 0) {
-			int len = count;
-
-			if (len > PAGE_SIZE)
-				len = PAGE_SIZE;
-			if (len) {
-				written = copy_from_user(kbuf, buf, len);
-				if (written) {
-					ssize_t ret;
-
-					free_page((unsigned long)kbuf);
-					ret = wrote + virtr + (len - written);
-					return ret ? ret : -EFAULT;
-				}
-			}
-			len = vwrite(kbuf, (char *)p, len);
-			count -= len;
-			buf += len;
-			virtr += len;
-			p += len;
-		}
-		free_page((unsigned long)kbuf);
-	}
-
- 	*ppos = p;
- 	return virtr + wrote;
-}
-
 #if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
 static ssize_t read_port(struct file * file, char __user * buf,
 			 size_t count, loff_t *ppos)
@@ -717,7 +617,6 @@ static struct file_operations mem_fops =
 static struct file_operations kmem_fops = {
 	.llseek		= memory_lseek,
 	.read		= read_kmem,
-	.write		= write_kmem,
 	.mmap		= mmap_kmem,
 	.open		= open_kmem,
 };
@@ -823,7 +722,6 @@ static const struct {
 	struct file_operations	*fops;
 } devlist[] = { /* list of minor devices */
 	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
-	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
 	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
 #if defined(CONFIG_ISA) || !defined(__mc68000__)
 	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/fs/proc/kcore.c linux-1050/fs/proc/kcore.c
--- linux-1020/fs/proc/kcore.c
+++ linux-1050/fs/proc/kcore.c
@@ -25,7 +25,7 @@
 
 static int open_kcore(struct inode * inode, struct file * filp)
 {
-	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+	return -EPERM;
 }
 
 static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *);
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-alpha/page.h linux-1050/include/asm-alpha/page.h
--- linux-1020/include/asm-alpha/page.h
+++ linux-1050/include/asm-alpha/page.h
@@ -110,6 +110,7 @@ extern __inline__ int get_order(unsigned
 #define VM_DATA_DEFAULT_FLAGS		(VM_READ | VM_WRITE | VM_EXEC | \
 					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
 #endif /* __KERNEL__ */
 
 #endif /* _ALPHA_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-arm/page.h linux-1050/include/asm-arm/page.h
--- linux-1020/include/asm-arm/page.h
+++ linux-1050/include/asm-arm/page.h
@@ -192,6 +192,8 @@ static inline int get_order(unsigned lon
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-arm26/page.h linux-1050/include/asm-arm26/page.h
--- linux-1020/include/asm-arm26/page.h
+++ linux-1050/include/asm-arm26/page.h
@@ -110,6 +110,8 @@ static inline int get_order(unsigned lon
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-cris/page.h linux-1050/include/asm-cris/page.h
--- linux-1020/include/asm-cris/page.h
+++ linux-1050/include/asm-cris/page.h
@@ -99,6 +99,8 @@ static inline int get_order(unsigned lon
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _CRIS_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-h8300/page.h linux-1050/include/asm-h8300/page.h
--- linux-1020/include/asm-h8300/page.h
+++ linux-1050/include/asm-h8300/page.h
@@ -99,6 +99,8 @@ extern unsigned long memory_end;
 
 #endif /* __ASSEMBLY__ */
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _H8300_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-i386/page.h linux-1050/include/asm-i386/page.h
--- linux-1020/include/asm-i386/page.h
+++ linux-1050/include/asm-i386/page.h
@@ -119,6 +119,8 @@ static __inline__ int get_order(unsigned
 
 extern int sysctl_legacy_va_layout;
 
+extern int devmem_is_allowed(unsigned long pagenr);
+
 #endif /* __ASSEMBLY__ */
 
 #ifdef __ASSEMBLY__
@@ -148,6 +150,8 @@ extern int sysctl_legacy_va_layout;
 	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
 		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+
+
 #endif /* __KERNEL__ */
 
 #endif /* _I386_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-ia64/page.h linux-1050/include/asm-ia64/page.h
--- linux-1020/include/asm-ia64/page.h
+++ linux-1050/include/asm-ia64/page.h
@@ -204,4 +204,6 @@ get_order (unsigned long size)
 					 (((current->personality & READ_IMPLIES_EXEC) != 0)	\
 					  ? VM_EXEC : 0))
 
+#define devmem_is_allowed(x) 1
+
 #endif /* _ASM_IA64_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-m68k/page.h linux-1050/include/asm-m68k/page.h
--- linux-1020/include/asm-m68k/page.h
+++ linux-1050/include/asm-m68k/page.h
@@ -190,6 +190,8 @@ static inline void *__va(unsigned long x
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _M68K_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-m68knommu/page.h linux-1050/include/asm-m68knommu/page.h
--- linux-1020/include/asm-m68knommu/page.h
+++ linux-1050/include/asm-m68knommu/page.h
@@ -96,6 +96,8 @@ extern unsigned long memory_end;
 
 #endif /* __ASSEMBLY__ */
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _M68KNOMMU_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-mips/page.h linux-1050/include/asm-mips/page.h
--- linux-1020/include/asm-mips/page.h
+++ linux-1050/include/asm-mips/page.h
@@ -148,4 +148,6 @@ static __inline__ int get_order(unsigned
 #define WANT_PAGE_VIRTUAL
 #endif
 
+#define devmem_is_allowed(x) 1
+
 #endif /* _ASM_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-parisc/page.h linux-1050/include/asm-parisc/page.h
--- linux-1020/include/asm-parisc/page.h
+++ linux-1050/include/asm-parisc/page.h
@@ -157,6 +157,8 @@ extern int npmem_ranges;
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _PARISC_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-ppc/page.h linux-1050/include/asm-ppc/page.h
--- linux-1020/include/asm-ppc/page.h
+++ linux-1050/include/asm-ppc/page.h
@@ -163,5 +163,7 @@ extern __inline__ int get_order(unsigned
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 #endif /* _PPC_PAGE_H */
--- linux-2.6.14/include/asm-powerpc/page.h~	2005-11-15 12:12:43.000000000 -0500
+++ linux-2.6.14/include/asm-powerpc/page.h	2005-11-15 12:13:21.000000000 -0500
@@ -174,6 +174,8 @@ extern int page_is_ram(unsigned long pfn
 
 #endif /* __ASSEMBLY__ */
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_POWERPC_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-s390/page.h linux-1050/include/asm-s390/page.h
--- linux-1020/include/asm-s390/page.h
+++ linux-1050/include/asm-s390/page.h
@@ -203,6 +203,8 @@ page_get_storage_key(unsigned long addr)
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _S390_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-sh/page.h linux-1050/include/asm-sh/page.h
--- linux-1020/include/asm-sh/page.h
+++ linux-1050/include/asm-sh/page.h
@@ -139,6 +139,8 @@ static __inline__ int get_order(unsigned
 
 #endif
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-sh64/page.h linux-1050/include/asm-sh64/page.h
--- linux-1020/include/asm-sh64/page.h
+++ linux-1050/include/asm-sh64/page.h
@@ -132,6 +132,8 @@ extern __inline__ int get_order(unsigned
 
 #endif
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH64_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-sparc/page.h linux-1050/include/asm-sparc/page.h
--- linux-1020/include/asm-sparc/page.h
+++ linux-1050/include/asm-sparc/page.h
@@ -176,6 +176,8 @@ extern unsigned long pfn_base;
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _SPARC_PAGE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-sparc64/page.h linux-1050/include/asm-sparc64/page.h
--- linux-1020/include/asm-sparc64/page.h
+++ linux-1050/include/asm-sparc64/page.h
@@ -156,6 +156,8 @@ static __inline__ int get_order(unsigned
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define devmem_is_allowed(x) 1
+
 #endif /* !(__KERNEL__) */
 
 #endif /* !(_SPARC64_PAGE_H) */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-um/page.h linux-1050/include/asm-um/page.h
--- linux-1020/include/asm-um/page.h
+++ linux-1050/include/asm-um/page.h
@@ -123,6 +123,7 @@ static __inline__ int get_order(unsigned
 
 extern struct page *arch_validate(struct page *page, int mask, int order);
 #define HAVE_ARCH_VALIDATE
+#define devmem_is_allowed(x) 1
 
 extern void arch_free_page(struct page *page, int order);
 #define HAVE_ARCH_FREE_PAGE
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-v850/page.h linux-1050/include/asm-v850/page.h
--- linux-1020/include/asm-v850/page.h
+++ linux-1050/include/asm-v850/page.h
@@ -141,6 +141,8 @@ extern __inline__ int get_order (unsigne
 #define __va(x)		     ((void *)__phys_to_virt ((unsigned long)(x)))
 
 
+#define devmem_is_allowed(x) 1
+
 #endif /* KERNEL */
 
 #endif /* __V850_PAGE_H__ */
diff -urNp --exclude-from=/home/davej/.exclude linux-1020/include/asm-x86_64/page.h linux-1050/include/asm-x86_64/page.h
--- linux-1020/include/asm-x86_64/page.h
+++ linux-1050/include/asm-x86_64/page.h
@@ -138,6 +138,10 @@ extern __inline__ int get_order(unsigned
 
 #define __HAVE_ARCH_GATE_AREA 1	
 
+#ifndef __ASSEMBLY__
+extern int devmem_is_allowed(unsigned long pagenr);
+#endif
+
 #endif /* __KERNEL__ */
 
 #endif /* _X86_64_PAGE_H */
--- linux-2.6.13/arch/x86_64/mm/init.c~	2005-09-13 01:17:03.000000000 -0400
+++ linux-2.6.13/arch/x86_64/mm/init.c	2005-09-13 01:18:03.000000000 -0400
@@ -414,6 +414,28 @@ unsigned long next_ram_page (unsigned lo
 
 EXPORT_SYMBOL_GPL(next_ram_page);
 
+static inline int page_is_ram (unsigned long pagenr)
+{
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		unsigned long addr, end;
+
+		if (e820.map[i].type != E820_RAM)	/* not usable memory */
+			continue;
+		/*
+		 * !!!FIXME!!! Some BIOSen report areas as RAM that
+		 * are not. Notably the 640->1Mb area. We need a sanity
+		 * check here.
+		 */
+		addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
+		end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
+		if  ((pagenr >= addr) && (pagenr < end))
+			return 1;
+	}
+	return 0;
+}
+
 /*
  * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
  * valid. The argument is a physical page number.

linux-2.6-diskdump.patch:
 drivers/block/Kconfig          |    5 
 drivers/block/Makefile         |    1 
 drivers/block/diskdump.c       | 1121 +++++++++++++++++++++++++++++++++++++++++
 include/asm-generic/diskdump.h |   13 
 include/asm-i386/diskdump.h    |   55 ++
 include/asm-ia64/diskdump.h    |   63 ++
 include/asm-powerpc/diskdump.h |   55 ++
 include/asm-ppc/diskdump.h     |    6 
 include/asm-s390/diskdump.h    |    6 
 include/asm-x86_64/diskdump.h  |   44 +
 include/linux/diskdump.h       |  186 ++++++
 include/linux/interrupt.h      |    4 
 include/linux/timer.h          |    3 
 include/linux/workqueue.h      |    3 
 kernel/softirq.c               |   32 +
 kernel/timer.c                 |   44 +
 kernel/workqueue.c             |   34 +
 17 files changed, 1671 insertions(+), 4 deletions(-)

--- NEW FILE linux-2.6-diskdump.patch ---
--- linux-2.6.12/drivers/block/Kconfig.diskdump.orig	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/drivers/block/Kconfig	2005-08-19 16:47:34.228261668 -0400
@@ -495,6 +495,11 @@ config CDROM_PKTCDVD_WCACHE
 	  this option is dangerous unless the CD-RW media is known good, as we
 	  don't do deferred write error handling yet.
 
+config DISKDUMP
+	tristate "Disk dump support"
+	---help---
+	  Disk dump support.
+
 source "drivers/s390/block/Kconfig"
 
 source "drivers/block/Kconfig.iosched"
--- linux-2.6.12/drivers/block/Makefile.diskdump.orig	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/drivers/block/Makefile	2005-08-19 16:47:34.229261501 -0400
@@ -45,3 +45,4 @@ obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
 obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
 
+obj-$(CONFIG_DISKDUMP)		+= diskdump.o
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/drivers/block/diskdump.c	2005-08-19 16:47:34.227261834 -0400
@@ -0,0 +1,1121 @@
+/*
+ *  linux/drivers/block/diskdump.c
+ *
+ *  Copyright (C) 2004  FUJITSU LIMITED
+ *  Copyright (C) 2002  Red Hat, Inc.
+ *  Written by Nobuhiro Tachino (ntachino at jp.fujitsu.com)
+ *
+ *  Some codes were derived from netdump and copyright belongs to
+ *  Red Hat, Inc.
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include <linux/smp_lock.h>
+#include <linux/nmi.h>
+#include <linux/crc32.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <linux/diskdump.h>
+#include <asm/diskdump.h>
+
+#define Dbg(x, ...)	pr_debug("disk_dump: " x "\n", ## __VA_ARGS__)
+#define Err(x, ...)	pr_err  ("disk_dump: " x "\n", ## __VA_ARGS__)
+#define Warn(x, ...)	pr_warn ("disk_dump: " x "\n", ## __VA_ARGS__)
+#define Info(x, ...)	pr_info ("disk_dump: " x "\n", ## __VA_ARGS__)
+
+#define ROUNDUP(x, y)	(((x) + ((y)-1))/(y))
+
+/* 512byte sectors to blocks */
+#define SECTOR_BLOCK(s)	((s) >> (DUMP_BLOCK_SHIFT - 9))
+
+/* The number of block which is used for saving format information */
+#define USER_PARAM_BLOCK	2
+
+static int fallback_on_err = 1;
+static int allow_risky_dumps = 1;
+static unsigned int block_order = 2;
+static int sample_rate = 8;
+module_param_named(fallback_on_err, fallback_on_err, bool, S_IRUGO|S_IWUSR);
+module_param_named(allow_risky_dumps, allow_risky_dumps, bool, S_IRUGO|S_IWUSR);
+module_param_named(block_order, block_order, uint, S_IRUGO|S_IWUSR);
+module_param_named(sample_rate, sample_rate, int, S_IRUGO|S_IWUSR);
+
+static unsigned long timestamp_1sec;
+static uint32_t module_crc;
+static char *scratch;
+static struct disk_dump_header dump_header;
+static struct disk_dump_sub_header dump_sub_header;
+
+/* Registered dump devices */
+static LIST_HEAD(disk_dump_devices);
+
+/* Registered dump types, e.g. SCSI, ... */
+static LIST_HEAD(disk_dump_types);
+
+static DECLARE_MUTEX(disk_dump_mutex);
+
+static unsigned int header_blocks;		/* The size of all headers */
+static unsigned int bitmap_blocks;		/* The size of bitmap header */
+static unsigned int total_ram_blocks;		/* The size of memory */
+static unsigned int total_blocks;		/* The sum of above */
+/*
+ * This is not a parameter actually, but used to pass the number of
+ * required blocks to userland tools
+ */
+module_param_named(total_blocks, total_blocks, uint, S_IRUGO);
+
+struct notifier_block *disk_dump_notifier_list;
+EXPORT_SYMBOL_GPL(disk_dump_notifier_list);
+
+unsigned long volatile diskdump_base_jiffies;
+void *diskdump_stack;
+enum disk_dump_states disk_dump_state = DISK_DUMP_INITIAL;
+
+extern int panic_timeout;
+extern unsigned long max_pfn;
+
+static asmlinkage void disk_dump(struct pt_regs *, void *);
+
+
+#ifdef CONFIG_SMP
+static void freeze_cpu(void *dummy)
+{
+	unsigned int cpu = smp_processor_id();
+
+	dump_header.tasks[cpu] = current;
+
+	platform_freeze_cpu();
+}
+#endif
+
+static int lapse = 0;		/* 200msec unit */
+
+static inline unsigned long eta(unsigned long nr, unsigned long maxnr)
+{
+	unsigned long long eta;
+
+	if (nr == 0)
+		nr = 1;
+
+	eta = ((maxnr << 8) / nr) * (unsigned long long)lapse;
+
+	return (unsigned long)(eta >> 8) - lapse;
+}
+
+static inline void print_status(unsigned int nr, unsigned int maxnr)
+{
+	static char *spinner = "/|\\-";
+	static unsigned long long prev_timestamp = 0;
+	unsigned long long timestamp;
+
+	if (nr == 0)
+		nr++;
+
+	platform_timestamp(timestamp);
+
+	if (timestamp - prev_timestamp > (timestamp_1sec/5)) {
+		prev_timestamp = timestamp;
+		lapse++;
+		printk("%u/%u    %lu ETA %c          \r",
+			nr, maxnr, eta(nr, maxnr) / 5, spinner[lapse & 3]);
+	}
+}
+
+static inline void clear_status(int nr, int maxnr)
+{
+	printk("                                       \r");
+	lapse = 0;
+}
+
+/*
+ * Checking the signature on a block. The format is as follows.
+ *
+ * 1st word = 'disk'
+ * 2nd word = 'dump'
+ * 3rd word = block number
+ * 4th word = ((block number + 7) * 11) & 0xffffffff
+ * 5th word = ((4th word + 7)* 11) & 0xffffffff
+ * ..
+ *
+ * Return 1 if the signature is correct, else return 0
+ */
+static int check_block_signature(void *buf, unsigned int block_nr)
+{
+	int word_nr = PAGE_SIZE / sizeof(int);
+	int *words = buf;
+	unsigned int val;
+	int i;
+
+	/*
+	 * Block 2 is used for the area which formatter saves options like
+	 * the sampling rate or the number of blocks. the Kernel part does not
+	 * check this block.
+	 */
+	if (block_nr == USER_PARAM_BLOCK)
+		return 1;
+
+	if (memcmp(buf, DUMP_PARTITION_SIGNATURE, sizeof(*words)))
+		return 0;
+
+	val = block_nr;
+	for (i = 2; i < word_nr; i++) {
+		if (words[i] != val)
+			return 0;
+		val = (val + 7) * 11;
+	}
+
+	return 1;
+}
+
+/*
+ * Read one block into the dump partition
+ */
+static int read_blocks(struct disk_dump_partition *dump_part, unsigned int nr,
+		       char *buf, int len)
+{
+	struct disk_dump_device *device = dump_part->device;
+	int ret;
+
+	local_irq_disable();
+	touch_nmi_watchdog();
+	ret = device->ops.rw_block(dump_part, READ, nr, buf, len);
+	if (ret < 0) {
+		Err("read error on block %u", nr);
+		return ret;
+	}
+	return 0;
+}
+
+static int write_blocks(struct disk_dump_partition *dump_part, unsigned int offs, char *buf, int len)
+{
+	struct disk_dump_device *device = dump_part->device;
+	int ret;
+
+	local_irq_disable();
+	touch_nmi_watchdog();
+	ret = device->ops.rw_block(dump_part, WRITE, offs, buf, len);
+	if (ret < 0) {
+		Err("write error on block %u", offs);
+		return ret;
+	}
+	return 0;
+}
+
+/*
+ * Initialize the common header
+ */
+
+/*
+ * Write the common header
+ */
+static int write_header(struct disk_dump_partition *dump_part)
+{
+	memset(scratch, 0, PAGE_SIZE);
+	memcpy(scratch, &dump_header, sizeof(dump_header));
+
+	return write_blocks(dump_part, 1, scratch, 1);
+}
+
+/*
+ * Check the signaures in all blocks of the dump partition
+ * Return 1 if the signature is correct, else return 0
+ */
+static int check_dump_partition(struct disk_dump_partition *dump_part,
+				unsigned int partition_size)
+{
+	unsigned int blk;
+	int ret;
+	unsigned int chunk_blks, skips;
+	int i;
+
+	if (sample_rate < 0)		/* No check */
+		return 1;
+
+	/*
+	 * If the device has limitations of transfer size, use it.
+	 */
+	chunk_blks = 1 << block_order;
+	if (dump_part->device->max_blocks)
+		 chunk_blks = min(chunk_blks, dump_part->device->max_blocks);
+	skips = chunk_blks << sample_rate;
+
+	lapse = 0;
+	for (blk = 0; blk < partition_size; blk += skips) {
+		unsigned int len;
+redo:
+		len = min(chunk_blks, partition_size - blk);
+		if ((ret = read_blocks(dump_part, blk, scratch, len)) < 0)
+			return 0;
+		print_status(blk + 1, partition_size);
+		for (i = 0; i < len; i++)
+			if (!check_block_signature(scratch + i * DUMP_BLOCK_SIZE, blk + i)) {
+				Err("bad signature in block %u", blk + i);
+				return 0;
+			}
+	}
+	/* Check the end of the dump partition */
+	if (blk - skips + chunk_blks < partition_size) {
+		blk = partition_size - chunk_blks;
+		goto redo;
+	}
+	clear_status(blk, partition_size);
+	return 1;
+}
+
+/*
+ * Write memory bitmap after location of dump headers.
+ */
+#define PAGE_PER_BLOCK	(PAGE_SIZE * 8)
+#define idx_to_pfn(nr, byte, bit) (((nr) * PAGE_SIZE + (byte)) * 8 + (bit))
+
+static int write_bitmap(struct disk_dump_partition *dump_part,
+			unsigned int bitmap_offset, unsigned int bitmap_blocks)
+{
+	unsigned int nr;
+	unsigned long pfn, next_ram_pfn;
+	int bit, byte;
+	int ret = 0;
+	unsigned char val;
+
+	for (nr = 0; nr < bitmap_blocks; nr++) {
+		pfn = idx_to_pfn(nr, 0, 0);
+		next_ram_pfn = next_ram_page(pfn - 1);
+
+		if (pfn + PAGE_PER_BLOCK <= next_ram_pfn)
+			memset(scratch, 0, PAGE_SIZE);
+		else
+			for (byte = 0; byte < PAGE_SIZE; byte++) {
+				val = 0;
+				for (bit = 0; bit < 8; bit++)
+					if (page_is_ram(idx_to_pfn(nr, byte,
+								   bit)))
+						val |= (1 << bit);
+				scratch[byte] = (char)val;
+			}
+		if ((ret = write_blocks(dump_part, bitmap_offset + nr,
+					scratch, 1)) < 0) {
+			Err("I/O error %d on block %u", ret, bitmap_offset + nr);
+			break;
+		}
+	}
+	return ret;
+}
+
+/*
+ * Write whole memory to dump partition.
+ * Return value is the number of writen blocks.
+ */
+static int write_memory(struct disk_dump_partition *dump_part, int offset,
+			unsigned int max_blocks_written,
+			unsigned int *blocks_written)
+{
+	char *kaddr;
+	unsigned int blocks = 0;
+	struct page *page;
+	unsigned long nr;
+	int ret = 0;
+	int blk_in_chunk = 0;
+
+	for (nr = next_ram_page(ULONG_MAX); nr < ULONG_MAX; nr = next_ram_page(nr)) {
+		print_status(blocks, max_blocks_written);
+
+
+		if (blocks >= max_blocks_written) {
+			Warn("dump device is too small. %lu pages were not saved", max_pfn - blocks);
+			goto out;
+		}
+
+		page = pfn_to_page(nr);
+		if (nr != page_to_pfn(page)) {
+			/* page_to_pfn() is called from kmap_atomic().
+			 * If page->flag is broken, it specified a wrong
+			 * zone and it causes kmap_atomic() fail.
+			 */
+			Err("Bad page. PFN %lu flags %lx\n",
+			    nr, (unsigned long)page->flags);
+			memset(scratch + blk_in_chunk * PAGE_SIZE, 0,
+			       PAGE_SIZE);
+			sprintf(scratch + blk_in_chunk * PAGE_SIZE,
+				"Bad page. PFN %lu flags %lx\n",
+			 	 nr, (unsigned long)page->flags);
+			goto write;
+		}
+
+		if (!kern_addr_valid((unsigned long)pfn_to_kaddr(nr))) {
+			memset(scratch + blk_in_chunk * PAGE_SIZE, 0,
+			       PAGE_SIZE);
+			sprintf(scratch + blk_in_chunk * PAGE_SIZE,
+				"Unmapped page. PFN %lu\n", nr);
+			goto write;
+		}
+
+		kaddr = kmap_atomic(page, KM_CRASHDUMP);
+		/*
+		 * need to copy because adapter drivers use
+		 * virt_to_bus()
+		 */
+		memcpy(scratch + blk_in_chunk * PAGE_SIZE, kaddr, PAGE_SIZE);
+		kunmap_atomic(kaddr, KM_CRASHDUMP);
+
+write:
+		blk_in_chunk++;
+		blocks++;
+
+		if (blk_in_chunk >= (1 << block_order)) {
+			ret = write_blocks(dump_part, offset, scratch,
+					   blk_in_chunk);
+			if (ret < 0) {
+				Err("I/O error %d on block %u", ret, offset);
+				break;
+			}
+			offset += blk_in_chunk;
+			blk_in_chunk = 0;
+		}
+	}
+	if (ret >= 0 && blk_in_chunk > 0) {
+		ret = write_blocks(dump_part, offset, scratch, blk_in_chunk);
+		if (ret < 0)
+			Err("I/O error %d on block %u", ret, offset);
+	}
+
+out:
+	clear_status(nr, max_blocks_written);
+
+	*blocks_written = blocks;
+	return ret;
+}
+
+/*
+ * Select most suitable dump device. sanity_check() returns the state
+ * of each dump device. 0 means OK, negative value means NG, and
+ * positive value means it maybe work. select_dump_partition() first
+ * try to select a sane device and if it has no sane device and
+ * allow_risky_dumps is set, it select one from maybe OK devices.
+ *
+ * XXX We cannot handle multiple partitions yet.
+ */
+static struct disk_dump_partition *select_dump_partition(void)
+{
+	struct disk_dump_device *dump_device;
+	struct disk_dump_partition *dump_part;
+	int sanity;
+	int strict_check = 1;
+
+redo:
+	/*
+	 * Select a sane polling driver.
+	 */
+	list_for_each_entry(dump_device, &disk_dump_devices, list) {
+		sanity = 0;
+		if (dump_device->ops.sanity_check)
+			sanity = dump_device->ops.sanity_check(dump_device);
+		if (sanity < 0 || (sanity > 0 && strict_check))
+			continue;
+		list_for_each_entry(dump_part, &dump_device->partitions, list)
+				return dump_part;
+	}
+	if (allow_risky_dumps && strict_check) {
+		strict_check = 0;
+		goto redo;
+	}
+	return NULL;
+}
+
+static int dump_err = 0;	/* Indicate Error state which occured in
+				 * disk_dump(). We need to make it global
+				 * because disk_dump() can't pass
+				 * error state as return value.
+				 */
+
+static void freeze_other_cpus(void)
+{
+#ifdef CONFIG_SMP
+	int	i;
+
+	smp_call_function(freeze_cpu, NULL, 1, -1);
+	diskdump_mdelay(3000);
+	printk("CPU frozen: ");
+	for (i = 0; i < NR_CPUS; i++) {
+		if (dump_header.tasks[i] != NULL)
+			printk("#%d", i);
+
+	}
+	printk("\n");
+	printk("CPU#%d is executing diskdump.\n", smp_processor_id());
+#else
+	diskdump_mdelay(1000);
+#endif
+	dump_header.tasks[smp_processor_id()] = current;
+}
+
+static void start_disk_dump(struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	/* Inhibit interrupt and stop other CPUs */
+	local_irq_save(flags);
+	preempt_disable();
+
+	/*
+	 * Check the checksum of myself
+	 */
+	if (down_trylock(&disk_dump_mutex)) {
+		Err("down_trylock(disk_dump_mutex) failed.");
+		goto done;
+	}
+
+	if (!check_crc_module()) {
+		Err("checksum error. diskdump common module may be compromised.");
+		goto done;
+	}
+
+	disk_dump_state = DISK_DUMP_RUNNING;
+
+	diskdump_mode = 1;
+
+	Dbg("notify dump start.");
+	notifier_call_chain(&disk_dump_notifier_list, 0, NULL);
+
+	touch_nmi_watchdog();
+	freeze_other_cpus();
+
+	/*
+	 *  Some platforms may want to execute netdump on its own stack.
+	 */
+	platform_start_crashdump(diskdump_stack, disk_dump, regs);
+
+done:
+	/*
+	 * If diskdump failed and fallback_on_err is set,
+	 * We just return and leave panic to netdump.
+	 */
+	if (dump_err) {
+		disk_dump_state = DISK_DUMP_FAILURE;
+		if (fallback_on_err && dump_err)
+			return;
+	} else {
+		disk_dump_state = DISK_DUMP_SUCCESS;
+	}
+
+	Dbg("notify panic.");
+	notifier_call_chain(&panic_notifier_list, 0, NULL);
+
+	if (panic_timeout > 0) {
+		int i;
+		/*
+	 	 * Delay timeout seconds before rebooting the machine. 
+		 * We can't use the "normal" timers since we just panicked..
+	 	 */
+		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
+		for (i = 0; i < panic_timeout; i++) {
+			touch_nmi_watchdog();
+			diskdump_mdelay(1000);
+		}
+
+		/*
+		 *	Should we run the reboot notifier. For the moment Im
+		 *	choosing not too. It might crash, be corrupt or do
+		 *	more harm than good for other reasons.
+		 */
+		machine_restart(NULL);
+	}
+	printk(KERN_EMERG "halt\n");
+	for (;;) {
+		touch_nmi_watchdog();
+		machine_halt();
+		diskdump_mdelay(1000);
+	}
+}
+
+static asmlinkage void disk_dump(struct pt_regs *regs, void *platform_arg)
+{
+	struct pt_regs myregs;
+	unsigned int max_written_blocks, written_blocks;
+	struct disk_dump_device *dump_device = NULL;
+	struct disk_dump_partition *dump_part = NULL;
+	int ret;
+
+	dump_err = -EIO;
+
+	/*
+	 * Setup timer/tasklet
+	 */
+	dump_clear_timers();
+	dump_clear_tasklet();
+	dump_clear_workqueue();
+
+	/* Save original jiffies value */
+	diskdump_base_jiffies = jiffies;
+
+	diskdump_setup_timestamp();
+
+	platform_fix_regs();
+
+	if (list_empty(&disk_dump_devices)) {
+		Err("adapter driver is not registered.");
+		goto done;
+	}
+
+	printk("start dumping\n");
+
+	if (!(dump_part = select_dump_partition())) {
+		Err("No sane dump device found");
+		goto done;
+	}
+	dump_device = dump_part->device;
+
+	/*
+	 * Stop ongoing I/O with polling driver and make the shift to I/O mode
+	 * for dump
+	 */
+	Dbg("do quiesce");
+	if (dump_device->ops.quiesce)
+		if ((ret = dump_device->ops.quiesce(dump_device)) < 0) {
+			Err("quiesce failed. error %d", ret);
+			goto done;
+		}
+
+	if (SECTOR_BLOCK(dump_part->nr_sects) < header_blocks + bitmap_blocks) {
+		Warn("dump partition is too small. Aborted");
+		goto done;
+	}
+
+	/* Check dump partition */
+	printk("check dump partition...\n");
+	if (!check_dump_partition(dump_part, total_blocks)) {
+		Err("check partition failed.");
+		goto done;
+	}
+
+	/*
+	 * Write the common header
+	 */
+	memcpy(dump_header.signature, DISK_DUMP_SIGNATURE,
+	       sizeof(dump_header.signature));
+	dump_header.utsname	     = system_utsname;
+	dump_header.timestamp	     = xtime;
+	dump_header.status	     = DUMP_HEADER_INCOMPLETED;
+	dump_header.block_size	     = PAGE_SIZE;
+	dump_header.sub_hdr_size     = size_of_sub_header();
+	dump_header.bitmap_blocks    = bitmap_blocks;
+	dump_header.max_mapnr	     = max_pfn;
+	dump_header.total_ram_blocks = total_ram_blocks;
+	dump_header.device_blocks    = SECTOR_BLOCK(dump_part->nr_sects);
+	dump_header.current_cpu	     = smp_processor_id();
+	dump_header.nr_cpus	     = num_online_cpus();
+	dump_header.written_blocks   = 2;
+
+	write_header(dump_part);
+
+	/*
+	 * Write the architecture dependent header
+	 */
+	Dbg("write sub header");
+	if ((ret = write_sub_header()) < 0) {
+		Err("writing sub header failed. error %d", ret);
+		goto done;
+	}
+
+	Dbg("writing memory bitmaps..");
+	if ((ret = write_bitmap(dump_part, header_blocks, bitmap_blocks)) < 0)
+		goto done;
+
+	max_written_blocks = total_ram_blocks;
+	if (dump_header.device_blocks < total_blocks) {
+		Warn("dump partition is too small. actual blocks %u. expected blocks %u. whole memory will not be saved",
+				dump_header.device_blocks, total_blocks);
+		max_written_blocks -= (total_blocks - dump_header.device_blocks);
+	}
+
+	dump_header.written_blocks += dump_header.sub_hdr_size;
+	dump_header.written_blocks += dump_header.bitmap_blocks;
+	write_header(dump_part);
+
+	printk("dumping memory..\n");
+	if ((ret = write_memory(dump_part, header_blocks + bitmap_blocks,
+				max_written_blocks, &written_blocks)) < 0)
+		goto done;
+
+	/*
+	 * Set the number of block that is written into and write it
+	 * into partition again.
+	 */
+	dump_header.written_blocks += written_blocks;
+	dump_header.status = DUMP_HEADER_COMPLETED;
+	write_header(dump_part);
+
+	dump_err = 0;
+
+done:
+	Dbg("do adapter shutdown.");
+	if (dump_device && dump_device->ops.shutdown)
+		if (dump_device->ops.shutdown(dump_device))
+			Err("adapter shutdown failed.");
+}
+
+static struct disk_dump_partition *find_dump_partition(struct block_device *bdev)
+{
+	struct disk_dump_device *dump_device;
+	struct disk_dump_partition *dump_part;
+
+	list_for_each_entry(dump_device, &disk_dump_devices, list)
+		list_for_each_entry(dump_part, &dump_device->partitions, list)
+			if (dump_part->bdev == bdev)
+				return dump_part;
+	return NULL;
+}
+
+static struct disk_dump_device *find_dump_device(struct disk_dump_device *device)
+{
+	struct disk_dump_device *dump_device;
+
+	list_for_each_entry(dump_device, &disk_dump_devices, list)
+		if (device->device == dump_device->device)
+			return  dump_device;
+	return NULL;
+}
+
+static void *find_real_device(struct device *dev,
+			      struct disk_dump_type **_dump_type)
+{
+	void *real_device;
+	struct disk_dump_type *dump_type;
+
+	list_for_each_entry(dump_type, &disk_dump_types, list)
+		if ((real_device = dump_type->probe(dev)) != NULL) {
+			*_dump_type = dump_type;
+			return real_device;
+		}
+	return NULL;
+}
+
+/*
+ * Add dump partition structure corresponding to file to the dump device
+ * structure.
+ */
+static int add_dump_partition(struct disk_dump_device *dump_device,
+			      struct block_device *bdev)
+{
+	struct disk_dump_partition *dump_part;
+	char buffer[BDEVNAME_SIZE];
+
+	if (!(dump_part = kmalloc(sizeof(*dump_part), GFP_KERNEL)))
+		return -ENOMEM;
+
+	dump_part->device = dump_device;
+	dump_part->bdev = bdev;
+
+	if (!bdev || !bdev->bd_part)
+		return -EINVAL;
+	dump_part->nr_sects   = bdev->bd_part->nr_sects;
+	dump_part->start_sect = bdev->bd_part->start_sect;
+
+	if (SECTOR_BLOCK(dump_part->nr_sects) < total_blocks)
+		Warn("%s is too small to save whole system memory\n",
+			bdevname(bdev, buffer));
+
+	list_add(&dump_part->list, &dump_device->partitions);
+
+	return 0;
+}
+
+/*
+ * Add dump device and partition.
+ * Must be called with disk_dump_mutex held.
+ */
+static int add_dump(struct device *dev, struct block_device *bdev)
+{
+	struct disk_dump_type *dump_type = NULL;
+	struct disk_dump_device *dump_device;
+	void *real_device;
+	int ret;
+
+	if ((ret = blkdev_get(bdev, FMODE_READ, 0)) < 0)
+		return ret;
+
+	/* Check whether this block device is already registered */
+	if (find_dump_partition(bdev)) {
+		blkdev_put(bdev);
+		return -EEXIST;
+	}
+
+	/* find dump_type and real device for this inode */
+	if (!(real_device = find_real_device(dev, &dump_type))) {
+		blkdev_put(bdev);
+		return -ENXIO;
+	}
+
+	/* Check whether this device is already registered */
+	dump_device = find_dump_device(real_device);
+	if (dump_device == NULL) {
+		/* real_device is not registered. create new dump_device */
+		if (!(dump_device = kmalloc(sizeof(*dump_device), GFP_KERNEL))) {
+			blkdev_put(bdev);
+			return -ENOMEM;
+		}
+
+		memset(dump_device, 0, sizeof(*dump_device));
+		INIT_LIST_HEAD(&dump_device->partitions);
+
+		dump_device->dump_type = dump_type;
+		dump_device->device = real_device;
+		if ((ret = dump_type->add_device(dump_device)) < 0) {
+			kfree(dump_device);
+			blkdev_put(bdev);
+			return ret;
+		}
+		if (!try_module_get(dump_type->owner))
+			return -EINVAL;
+		list_add(&dump_device->list, &disk_dump_devices);
+	}
+
+	ret = add_dump_partition(dump_device, bdev);
+	if (ret < 0 && list_empty(&dump_device->list)) {
+		dump_type->remove_device(dump_device);
+		module_put(dump_type->owner);
+		list_del(&dump_device->list);
+		kfree(dump_device);
+	}
+	if (ret < 0)
+		blkdev_put(bdev);
+
+	return ret;
+}
+
+/*
+ * Remove dump partition corresponding to bdev.
+ * Must be called with disk_dump_mutex held.
+ */
+static int remove_dump(struct block_device *bdev)
+{
+	struct disk_dump_device *dump_device;
+	struct disk_dump_partition *dump_part;
+	struct disk_dump_type *dump_type;
+
+	if (!(dump_part = find_dump_partition(bdev))) {
+		bdput(bdev);
+		return -ENOENT;
+	}
+
+	blkdev_put(bdev);
+	dump_device = dump_part->device;
+	list_del(&dump_part->list);
+	kfree(dump_part);
+
+	if (list_empty(&dump_device->partitions)) {
+		dump_type = dump_device->dump_type;
+		dump_type->remove_device(dump_device);
+		module_put(dump_type->owner);
+		list_del(&dump_device->list);
+		kfree(dump_device);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+static struct disk_dump_partition *dump_part_by_pos(struct seq_file *seq,
+						    loff_t pos)
+{
+	struct disk_dump_device *dump_device;
+	struct disk_dump_partition *dump_part;
+
+	list_for_each_entry(dump_device, &disk_dump_devices, list) {
+		seq->private = dump_device;
+		list_for_each_entry(dump_part, &dump_device->partitions, list)
+			if (!pos--)
+				return dump_part;
+	}
+	return NULL;
+}
+
+static void *disk_dump_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	loff_t n = *pos;
+
+	down(&disk_dump_mutex);
+
+	if (!n--)
+		return (void *)1;	/* header */
+
+	return dump_part_by_pos(seq, n);
+}
+
+static void *disk_dump_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct list_head *partition = v;
+	struct list_head *device = seq->private;
+	struct disk_dump_device *dump_device;
+
+	(*pos)++;
+	if (v == (void *)1)
+		return dump_part_by_pos(seq, 0);
+
+	dump_device = list_entry(device, struct disk_dump_device, list);
+
+	partition = partition->next;
+	if (partition != &dump_device->partitions)
+		return partition;
+
+	device = device->next;
+	seq->private = device;
+	if (device == &disk_dump_devices)
+		return NULL;
+
+	dump_device = list_entry(device, struct disk_dump_device, list);
+
+	return dump_device->partitions.next;
+}
+
+static void disk_dump_seq_stop(struct seq_file *seq, void *v)
+{
+	up(&disk_dump_mutex);
+}
+
+static int disk_dump_seq_show(struct seq_file *seq, void *v)
+{
+	struct disk_dump_partition *dump_part = v;
+	char buf[BDEVNAME_SIZE];
+
+	if (v == (void *)1) {	/* header */
+		seq_printf(seq, "# sample_rate: %u\n", sample_rate);
+		seq_printf(seq, "# block_order: %u\n", block_order);
+		seq_printf(seq, "# fallback_on_err: %u\n", fallback_on_err);
+		seq_printf(seq, "# allow_risky_dumps: %u\n", allow_risky_dumps);
+		seq_printf(seq, "# total_blocks: %u\n", total_blocks);
+		seq_printf(seq, "#\n");
+
+		return 0;
+	}
+
+	seq_printf(seq, "%s %lu %lu\n", bdevname(dump_part->bdev, buf),
+			dump_part->start_sect, dump_part->nr_sects);
+	return 0;
+}
+
+static struct seq_operations disk_dump_seq_ops = {
+	.start	= disk_dump_seq_start,
+	.next	= disk_dump_seq_next,
+	.stop	= disk_dump_seq_stop,
+	.show	= disk_dump_seq_show,
+};
+
+static int disk_dump_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &disk_dump_seq_ops);
+}
+
+static struct file_operations disk_dump_fops = {
+	.owner		= THIS_MODULE,
+	.open		= disk_dump_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+#endif
+
+int register_disk_dump_device(struct device *dev, struct block_device *bdev)
+{
+	int ret;
+
+	down(&disk_dump_mutex);
+	ret = add_dump(dev, bdev);
+	set_crc_modules();
+	up(&disk_dump_mutex);
+
+	return ret;
+}
+
+int unregister_disk_dump_device(struct block_device *bdev)
+{
+	int ret;
+
+	down(&disk_dump_mutex);
+	ret = remove_dump(bdev);
+	set_crc_modules();
+	up(&disk_dump_mutex);
+
+	return ret;
+}
+
+int find_disk_dump_device(struct block_device *bdev)
+{
+	int ret;
+
+	down(&disk_dump_mutex);
+	ret = (find_dump_partition(bdev) != NULL);
+	up(&disk_dump_mutex);
+
+	return ret;
+}
+
+int register_disk_dump_type(struct disk_dump_type *dump_type)
+{
+	down(&disk_dump_mutex);
+	list_add(&dump_type->list, &disk_dump_types);
+	set_crc_modules();
+	up(&disk_dump_mutex);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(register_disk_dump_type);
+
+int unregister_disk_dump_type(struct disk_dump_type *dump_type)
+{
+	down(&disk_dump_mutex);
+	list_del(&dump_type->list);
+	set_crc_modules();
+	up(&disk_dump_mutex);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(unregister_disk_dump_type);
+
+static void compute_total_blocks(void)
+{
+	unsigned long nr;
+
+	/*
+	 * the number of block of the common header and the header
+	 * that is depend on the architecture
+	 *
+	 * block 0:		dump partition header
+	 * block 1:		dump header
+	 * block 2:		dump subheader
+	 * block 3..n:		memory bitmap
+	 * block (n + 1)...:	saved memory
+	 *
+	 * We never overwrite block 0
+	 */
+	header_blocks = 2 + size_of_sub_header();
+
+	total_ram_blocks = 0;
+	for (nr = next_ram_page(ULONG_MAX); nr < ULONG_MAX; nr = next_ram_page(nr))
+		total_ram_blocks++;
+
+	bitmap_blocks = ROUNDUP(max_pfn, 8 * PAGE_SIZE);
+
+	/*
+	 * The necessary size of area for dump is:
+	 * 1 block for common header
+	 * m blocks for architecture dependent header
+	 * n blocks for memory bitmap
+	 * and whole memory
+	 */
+	total_blocks = header_blocks + bitmap_blocks + total_ram_blocks;
+
+	Info("total blocks required: %u (header %u + bitmap %u + memory %u)",
+		total_blocks, header_blocks, bitmap_blocks, total_ram_blocks);
+}
+
+struct disk_dump_ops dump_ops = {
+	.add_dump	= register_disk_dump_device,
+	.remove_dump	= unregister_disk_dump_device,
+	.find_dump	= find_disk_dump_device,
+};
+
+static int init_diskdump(void)
+{
+	unsigned long long t0;
+	unsigned long long t1;
+	struct page *page;
+
+	if (!platform_supports_diskdump) {
+		Err("platform does not support diskdump.");
+		return -1;
+	}
+
+	/* Allocate one block that is used temporally */
+	do {
+		page = alloc_pages(GFP_KERNEL, block_order);
+		if (page != NULL)
+			break;
+	} while (--block_order >= 0);
+	if (!page) {
+		Err("alloc_pages failed.");
+		return -1;
+	}
+	scratch = page_address(page);
+	Info("Maximum block size: %lu", PAGE_SIZE << block_order);
+
+	if (diskdump_register_hook(start_disk_dump)) {
+		Err("failed to register hooks.");
+		return -1;
+	}
+
+	if (diskdump_register_ops(&dump_ops)) {
+		Err("failed to register ops.");
+		return -1;
+	}
+
+	compute_total_blocks();
+
+	platform_timestamp(t0);
+	diskdump_mdelay(1);
+	platform_timestamp(t1);
+	timestamp_1sec = (unsigned long)(t1 - t0) * 1000;
+
+	/*
+	 *  Allocate a separate stack for diskdump.
+	 */
+	platform_init_stack(&diskdump_stack);
+
+	down(&disk_dump_mutex);
+	set_crc_modules();
+	up(&disk_dump_mutex);
+
+#ifdef CONFIG_PROC_FS
+	{
+		struct proc_dir_entry *p;
+
+		p = create_proc_entry("diskdump", S_IRUGO|S_IWUSR, NULL);
+		if (p)
+			p->proc_fops = &disk_dump_fops;
+	}
+#endif
+
+	return 0;
+}
+
+static void cleanup_diskdump(void)
+{
+	Info("shut down.");
+	diskdump_unregister_hook();
+	diskdump_unregister_ops();
+	platform_cleanup_stack(diskdump_stack);
+	free_pages((unsigned long)scratch, block_order);
+#ifdef CONFIG_PROC_FS
+	remove_proc_entry("diskdump", NULL);
+#endif
+}
+
+module_init(init_diskdump);
+module_exit(cleanup_diskdump);
+
+MODULE_LICENSE("GPL");
--- linux-2.6.12/kernel/workqueue.c.diskdump.orig	2005-08-19 16:44:33.085478791 -0400
+++ linux-2.6.12/kernel/workqueue.c	2005-08-19 16:47:34.249258165 -0400
@@ -467,6 +467,37 @@ int current_is_keventd(void)
 
 }
 
+static struct cpu_workqueue_struct saved_cwq;
+
+void dump_clear_workqueue(void)
+{
+	int cpu = smp_processor_id();
+	struct cpu_workqueue_struct *cwq = keventd_wq->cpu_wq + cpu;
+
+	memcpy(&saved_cwq, cwq, sizeof(saved_cwq));
+	spin_lock_init(&cwq->lock);
+	INIT_LIST_HEAD(&cwq->worklist);
+	init_waitqueue_head(&cwq->more_work);
+	init_waitqueue_head(&cwq->work_done);
+}
+
+void dump_run_workqueue(void)
+{
+	struct cpu_workqueue_struct *cwq;
+
+	cwq = keventd_wq->cpu_wq + smp_processor_id();
+	while (!list_empty(&cwq->worklist)) {
+		struct work_struct *work = list_entry(cwq->worklist.next,
+						struct work_struct, entry);
+		void (*f) (void *) = work->func;
+		void *data = work->data;
+
+		list_del_init(cwq->worklist.next);
+		clear_bit(0, &work->pending);
+		f(data);
+	}
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 /* Take the work from this (downed) CPU. */
 static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
@@ -552,3 +583,6 @@ EXPORT_SYMBOL(schedule_work);
 EXPORT_SYMBOL(schedule_delayed_work);
 EXPORT_SYMBOL(schedule_delayed_work_on);
 EXPORT_SYMBOL(flush_scheduled_work);
+
+EXPORT_SYMBOL_GPL(dump_clear_workqueue);
+EXPORT_SYMBOL_GPL(dump_run_workqueue);
--- linux-2.6.12/kernel/softirq.c.diskdump.orig	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/kernel/softirq.c	2005-08-19 16:47:34.242259333 -0400
@@ -341,6 +341,38 @@ void tasklet_kill(struct tasklet_struct 
 
 EXPORT_SYMBOL(tasklet_kill);
 
+struct tasklet_head saved_tasklet;
+
+void dump_clear_tasklet(void)
+{
+	saved_tasklet.list = __get_cpu_var(tasklet_vec).list;
+	__get_cpu_var(tasklet_vec).list = NULL;
+}
+
+EXPORT_SYMBOL_GPL(dump_clear_tasklet);
+
+void dump_run_tasklet(void)
+{
+	struct tasklet_struct *list;
+
+	list = __get_cpu_var(tasklet_vec).list;
+	__get_cpu_var(tasklet_vec).list = NULL;
+
+	while (list) {
+		struct tasklet_struct *t = list;
+		list = list->next;
+
+		if (!atomic_read(&t->count) &&
+		    (test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)))
+				t->func(t->data);
+
+		t->next = __get_cpu_var(tasklet_vec).list;
+		__get_cpu_var(tasklet_vec).list = t;
+	}
+}
+
+EXPORT_SYMBOL_GPL(dump_run_tasklet);
+
 void __init softirq_init(void)
 {
 	open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL);
--- linux-2.6.12/kernel/timer.c.diskdump.orig	2005-08-19 16:44:27.502410144 -0400
+++ linux-2.6.12/kernel/timer.c	2005-08-19 16:49:13.988620772 -0400
@@ -33,6 +33,8 @@
 #include <linux/posix-timers.h>
 #include <linux/cpu.h>
 #include <linux/syscalls.h>
+#include <linux/delay.h>
+#include <linux/diskdump.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -460,8 +462,9 @@ static int cascade(tvec_base_t *base, tv
 static inline void __run_timers(tvec_base_t *base)
 {
 	struct timer_list *timer;
+	unsigned long flags;
 
-	spin_lock_irq(&base->t_base.lock);
+	spin_lock_irqsave(&base->t_base.lock, flags);
 	while (time_after_eq(jiffies, base->timer_jiffies)) {
 		struct list_head work_list = LIST_HEAD_INIT(work_list);
 		struct list_head *head = &work_list;
@@ -487,7 +490,7 @@ static inline void __run_timers(tvec_bas
 
 			set_running_timer(base, timer);
 			detach_timer(timer, 1);
-			spin_unlock_irq(&base->t_base.lock);
+			spin_unlock_irqrestore(&base->t_base.lock, flags);
 			{
 				int preempt_count = preempt_count();
 				fn(data);
@@ -504,7 +507,7 @@ static inline void __run_timers(tvec_bas
 		}
 	}
 	set_running_timer(base, NULL);
-	spin_unlock_irq(&base->t_base.lock);
+	spin_unlock_irqrestore(&base->t_base.lock, flags);
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
@@ -1104,6 +1107,12 @@ fastcall signed long __sched schedule_ti
 	struct timer_list timer;
 	unsigned long expire;
 
+	if (crashdump_mode()) {
+		diskdump_mdelay(timeout);
+		set_current_state(TASK_RUNNING);
+		return timeout;
+	}
+
 	switch (timeout)
 	{
 	case MAX_SCHEDULE_TIMEOUT:
@@ -1306,7 +1315,7 @@ asmlinkage long sys_sysinfo(struct sysin
 	return 0;
 }
 
-static void __devinit init_timers_cpu(int cpu)
+static void /* __devinit */ init_timers_cpu(int cpu)
 {
 	int j;
 	tvec_base_t *base;
@@ -1325,6 +1334,27 @@ static void __devinit init_timers_cpu(in
 	base->timer_jiffies = jiffies;
 }
 
+static tvec_base_t saved_tvec_base;
+
+void dump_clear_timers(void)
+{
+	tvec_base_t *base = &per_cpu(tvec_bases, smp_processor_id());
+
+	memcpy(&saved_tvec_base, base, sizeof(saved_tvec_base));
+	init_timers_cpu(smp_processor_id());
+}
+
+EXPORT_SYMBOL_GPL(dump_clear_timers);
+
+void dump_run_timers(void)
+{
+	tvec_base_t *base = &__get_cpu_var(tvec_bases);
+
+	__run_timers(base);
+}
+
+EXPORT_SYMBOL_GPL(dump_run_timers);
+
 #ifdef CONFIG_HOTPLUG_CPU
 static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
 {
@@ -1640,6 +1640,12 @@ void msleep(unsigned int msecs)
 {
 	unsigned long timeout = msecs_to_jiffies(msecs) + 1;
 
+	if (unlikely(crashdump_mode())) {
+		while (msecs--)
+			udelay(1000);
+		return;
+	}
+
 	while (timeout)
 		timeout = schedule_timeout_uninterruptible(timeout);
 }
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-ia64/diskdump.h	2005-08-19 16:47:34.231261167 -0400
@@ -0,0 +1,63 @@
+#ifndef _ASM_IA64_DISKDUMP_H
+#define _ASM_IA64_DISKDUMP_H
+
+/*
+ * linux/include/asm-ia64/diskdump.h
+ *
+ * Copyright (c) 2004 FUJITSU LIMITED
+ * Copyright (c) 2003 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/crashdump.h>
+
+
+const static int platform_supports_diskdump = 1;
+
+struct disk_dump_sub_header {
+	elf_gregset_t		 elf_regs;
+	struct switch_stack	*sw[NR_CPUS];
+};
+
+#define size_of_sub_header()	((sizeof(struct disk_dump_sub_header) + PAGE_SIZE - 1) / DUMP_BLOCK_SIZE)
+
+#define write_sub_header() \
+({								\
+ 	int ret;						\
+	struct unw_frame_info *info = platform_arg;		\
+								\
+	ia64_do_copy_regs(info, &dump_sub_header.elf_regs);	\
+	dump_sub_header.sw[smp_processor_id()] = info->sw;	\
+	clear_page(scratch);					\
+	memcpy(scratch, &dump_sub_header, sizeof(dump_sub_header));\
+ 								\
+	if ((ret = write_blocks(dump_part, 2, scratch, 1)) >= 0)\
+		ret = 1; /* size of sub header in page */;	\
+	ret;							\
+})
+
+#define platform_freeze_cpu() 					\
+{								\
+	unw_init_running(ia64_freeze_cpu,			\
+		&dump_sub_header.sw[smp_processor_id()]);	\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IA64_DISKDUMP_H */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-x86_64/diskdump.h	2005-08-19 16:47:34.234260667 -0400
@@ -0,0 +1,44 @@
+/*
+ * include/asm-x86_64/diskdump.h
+ *
+ * Copyright (C) Hitachi, Ltd. 2004
+ * Written by Satoshi Oshima (oshima at sdl.hitachi.co.jp)
+ *
+ * Derived from include/asm-i386/diskdump.h
+ * Copyright (c) 2004 FUJITSU LIMITED
+ * Copyright (c) 2003 Red Hat, Inc. All rights reserved.
+ *
+ */
+
+#ifndef _ASM_X86_64_DISKDUMP_H
+#define _ASM_X86_64_DISKDUMP_H
+
+#ifdef __KERNEL__
+
+#include <linux/elf.h>
+#include <asm/crashdump.h>
+
+const static int platform_supports_diskdump = 1;
+
+struct disk_dump_sub_header {
+	elf_gregset_t		elf_regs;
+};
+
+#define size_of_sub_header()	((sizeof(struct disk_dump_sub_header) + PAGE_SIZE - 1) / DUMP_BLOCK_SIZE)
+
+#define write_sub_header() 						\
+({									\
+ 	int ret;							\
+									\
+	ELF_CORE_COPY_REGS(dump_sub_header.elf_regs, (&myregs));	\
+	clear_page(scratch);						\
+	memcpy(scratch, &dump_sub_header, sizeof(dump_sub_header));	\
+ 									\
+	if ((ret = write_blocks(dump_part, 2, scratch, 1)) >= 0)	\
+		ret = 1; /* size of sub header in page */;		\
+	ret;								\
+})
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_X86_64_DISKDUMP_H */
--- linux-2.6.12/include/linux/timer.h.diskdump.orig	2005-08-19 16:44:27.131472023 -0400
+++ linux-2.6.12/include/linux/timer.h	2005-08-19 16:47:34.239259833 -0400
@@ -89,4 +89,7 @@ extern void init_timers(void);
 extern void run_local_timers(void);
 extern void it_real_fn(unsigned long);
 
+extern void dump_clear_timers(void);
+extern void dump_run_timers(void);
+
 #endif
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/linux/diskdump.h	2005-08-19 16:47:34.236260333 -0400
@@ -0,0 +1,186 @@
+#ifndef _LINUX_DISKDUMP_H
+#define _LINUX_DISKDUMP_H
+
+/*
+ * linux/include/linux/diskdump.h
+ *
+ * Copyright (c) 2004 FUJITSU LIMITED
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/list.h>
+#include <linux/blkdev.h>
+#include <linux/utsname.h>
+#include <linux/device.h>
+
+/* The minimum Dump I/O unit. Must be the same of PAGE_SIZE */
+#define DUMP_BLOCK_SIZE		PAGE_SIZE
+#define DUMP_BLOCK_SHIFT	PAGE_SHIFT
+
+int diskdump_register_hook(void (*dump_func)(struct pt_regs *));
+void diskdump_unregister_hook(void);
+
+/*
+ * The handler of diskdump module
+ */
+struct disk_dump_ops {
+	int (*add_dump)(struct device *, struct block_device *);
+	int (*remove_dump)(struct block_device *);
+	int (*find_dump)(struct block_device *);
+};
+
+int diskdump_register_ops(struct disk_dump_ops* op);
+void diskdump_unregister_ops(void);
+
+
+/*
+ * The handler that adapter driver provides for the common module of
+ * dump
+ */
+struct disk_dump_partition;
+struct disk_dump_device;
+
+struct disk_dump_type {
+	void *(*probe)(struct device *);
+	int (*add_device)(struct disk_dump_device *);
+	void (*remove_device)(struct disk_dump_device *);
+	struct module *owner;
+	struct list_head list;
+};
+
+struct disk_dump_device_ops {
+	int (*sanity_check)(struct disk_dump_device *);
+	int (*quiesce)(struct disk_dump_device *);
+	int (*shutdown)(struct disk_dump_device *);
+	int (*rw_block)(struct disk_dump_partition *, int rw, unsigned long block_nr, void *buf, int len);
+};
+
+/* The data structure for a dump device */
+struct disk_dump_device {
+	struct list_head list;
+	struct disk_dump_device_ops ops;
+	struct disk_dump_type *dump_type;
+	void *device;
+	unsigned int max_blocks;
+	struct list_head partitions;
+};
+
+/* The data structure for a dump partition */
+struct disk_dump_partition {
+	struct list_head list;
+	struct disk_dump_device *device;
+	struct block_device *bdev;
+	unsigned long start_sect;
+	unsigned long nr_sects;
+};
+
+int register_disk_dump_type(struct disk_dump_type *);
+int unregister_disk_dump_type(struct disk_dump_type *);
+
+
+/*
+ * sysfs interface
+ */
+ssize_t diskdump_sysfs_store(struct device *dev, const char *buf, size_t count);
+ssize_t diskdump_sysfs_show(struct device *dev, char *buf);
+
+
+void diskdump_update(void);
+void diskdump_setup_timestamp(void);
+
+/* mdelay() is trapped by WARN_ON if we are in the interrupt context. */
+#define diskdump_mdelay(n) \
+({unsigned long __ms=(n); while (__ms--) udelay(1000);})
+
+
+/*
+ * Architecture-independent dump header
+ */
+
+/* The signature which is written in each block in the dump partition */
+#define DISK_DUMP_SIGNATURE		"DISKDUMP"
+#define DISK_DUMP_HEADER_VERSION	1
+
+#define DUMP_PARTITION_SIGNATURE	"diskdump"
+
+#define DUMP_HEADER_COMPLETED	0
+#define DUMP_HEADER_INCOMPLETED	1
+
+struct disk_dump_header {
+	char			signature[8];	/* = "DISKDUMP" */
+	int			header_version;	/* Dump header version */
+	struct new_utsname	utsname;	/* copy of system_utsname */
+	struct timespec		timestamp;	/* Time stamp */
+	unsigned int		status;		/* Above flags */
+	int			block_size;	/* Size of a block in byte */
+	int			sub_hdr_size;	/* Size of arch dependent
+						   header in blocks */
+	unsigned int		bitmap_blocks;	/* Size of Memory bitmap in
+						   block */
+	unsigned int		max_mapnr;	/* = max_mapnr */
+	unsigned int		total_ram_blocks;/* Size of Memory in block */
+	unsigned int		device_blocks;	/* Number of total blocks in
+						 * the dump device */
+	unsigned int		written_blocks;	/* Number of written blocks */
+	unsigned int		current_cpu;	/* CPU# which handles dump */
+	int			nr_cpus;	/* Number of CPUs */
+	struct task_struct	*tasks[NR_CPUS];
+};
+
+/* Diskdump state */
+extern enum disk_dump_states {
+	DISK_DUMP_INITIAL,
+	DISK_DUMP_RUNNING,
+	DISK_DUMP_SUCCESS,
+	DISK_DUMP_FAILURE,
+}  disk_dump_state;
+
+/*
+ * Calculate the check sum of the whole module
+ */
+#define get_crc_module()						\
+({									\
+	struct module *module = &__this_module;				\
+	crc32_le(0, (char *)(module->module_core),			\
+	  ((unsigned long)module - (unsigned long)(module->module_core))); \
+})
+
+/* Calculate the checksum of the whole module */
+#define set_crc_modules()						\
+({									\
+	module_crc = 0;							\
+	module_crc = get_crc_module();					\
+})
+
+/*
+ * Compare the checksum value that is stored in module_crc to the check
+ * sum of current whole module. Must be called with holding disk_dump_lock.
+ * Return TRUE if they are the same, else return FALSE
+ *
+ */
+#define check_crc_module()						\
+({									\
+	uint32_t orig_crc, cur_crc;					\
+									\
+	orig_crc = module_crc; module_crc = 0;				\
+	cur_crc = get_crc_module();					\
+	module_crc = orig_crc;						\
+	orig_crc == cur_crc;						\
+})
+
+
+#endif /* _LINUX_DISKDUMP_H */
--- linux-2.6.12/include/linux/interrupt.h.diskdump.orig	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/include/linux/interrupt.h	2005-08-19 16:47:34.237260167 -0400
@@ -286,4 +286,8 @@ extern int probe_irq_off(unsigned long);
 extern unsigned int probe_irq_mask(unsigned long);	/* returns mask of ISA interrupts */
 #endif
 
+
+extern void dump_clear_tasklet(void);
+extern void dump_run_tasklet(void);
+
 #endif
--- linux-2.6.12/include/linux/workqueue.h.diskdump.orig	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/include/linux/workqueue.h	2005-08-19 16:47:34.240259666 -0400
@@ -89,4 +89,7 @@ static inline int cancel_delayed_work(st
 	return ret;
 }
 
+extern void dump_clear_workqueue(void);
+extern void dump_run_workqueue(void);
+
 #endif
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-ppc/diskdump.h	2005-08-19 16:47:34.232261001 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_PPC64_DISKDUMP_H_
+#define _ASM_PPC64_DISKDUMP_H_
+
+#include <asm-generic/diskdump.h>
+
+#endif /* _ASM_PPC64_DISKDUMP_H_ */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-generic/diskdump.h	2005-08-19 16:47:34.229261501 -0400
@@ -0,0 +1,13 @@
+#ifndef _ASM_GENERIC_DISKDUMP_H_
+#define _ASM_GENERIC_DISKDUMP_H_
+
+#include <asm-generic/crashdump.h>
+
+const static int platform_supports_diskdump = 0;
+
+struct disk_dump_sub_header {};
+
+#define size_of_sub_header()	1
+#define write_sub_header() 	1
+
+#endif /* _ASM_GENERIC_DISKDUMP_H */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-powerpc/diskdump.h	2005-08-19 16:47:34.233260834 -0400
@@ -0,0 +1,55 @@
+#ifndef _ASM_PPC64_DISKDUMP_H_
+#define _ASM_PPC64_DISKDUMP_H_
+
+/*
+ * linux/include/asm-ppc64/diskdump.h
+ *
+ * Copyright (c) 2004 FUJITSU LIMITED
+ * Copyright (c) 2003 Red Hat, Inc. All rights reserved.
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/elf.h>
+#include <asm/crashdump.h>
+
+const static int platform_supports_diskdump = 1;
+
+struct disk_dump_sub_header {
+	elf_gregset_t		elf_regs;
+};
+
+#define size_of_sub_header()	((sizeof(struct disk_dump_sub_header) + PAGE_SIZE - 1) / DUMP_BLOCK_SIZE)
+
+#define write_sub_header() \
+({								\
+	int ret;						\
+	struct disk_dump_sub_header *header;			\
+								\
+	header = (struct disk_dump_sub_header *)scratch;	\
+	ELF_CORE_COPY_REGS(header->elf_regs, (&myregs));	\
+	clear_page(scratch);					\
+	if ((ret = write_blocks(dump_part, 2, scratch, 1)) >= 0)\
+		ret = 1; /* size of sub header in page */;	\
+	ret;							\
+})
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_PPC64_DISKDUMP_H_ */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-i386/diskdump.h	2005-08-19 16:47:34.230261334 -0400
@@ -0,0 +1,55 @@
+#ifndef _ASM_I386_DISKDUMP_H
+#define _ASM_I386_DISKDUMP_H
+
+/*
+ * linux/include/asm-i386/diskdump.h
+ *
+ * Copyright (c) 2004 FUJITSU LIMITED
+ * Copyright (c) 2003 Red Hat, Inc. All rights reserved.
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/elf.h>
+#include <asm/crashdump.h>
+
+const static int platform_supports_diskdump = 1;
+
+struct disk_dump_sub_header {
+	elf_gregset_t		elf_regs;
+};
+
+#define size_of_sub_header()	((sizeof(struct disk_dump_sub_header) + PAGE_SIZE - 1) / DUMP_BLOCK_SIZE)
+
+#define write_sub_header() 						\
+({									\
+ 	int ret;							\
+									\
+	ELF_CORE_COPY_REGS(dump_sub_header.elf_regs, (&myregs));	\
+	clear_page(scratch);						\
+	memcpy(scratch, &dump_sub_header, sizeof(dump_sub_header));	\
+ 									\
+	if ((ret = write_blocks(dump_part, 2, scratch, 1)) >= 0)	\
+		ret = 1; /* size of sub header in page */;		\
+	ret;								\
+})
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_I386_DISKDUMP_H */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-s390/diskdump.h	2005-08-19 16:47:34.234260667 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_S390_DISKDUMP_H_
+#define _ASM_S390_DISKDUMP_H_
+
+#include <asm-generic/diskdump.h>
+
+#endif /* _ASM_S390_DISKDUMP_H_ */

linux-2.6-dump_smp_call_function.patch:
 arch/i386/kernel/smp.c    |   44 ++++++++++++++++++++++++++++++++++++++++++++
 arch/ia64/kernel/smp.c    |   44 ++++++++++++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/smp.c |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 arch/x86_64/kernel/smp.c  |   45 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/block/diskdump.c  |    2 +-
 drivers/net/netdump.c     |    2 +-
 include/linux/smp.h       |    2 ++
 7 files changed, 181 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6-dump_smp_call_function.patch ---
--- linux-2.6.12/arch/ia64/kernel/smp.c.orig	2005-08-23 10:49:52.398379464 -0400
+++ linux-2.6.12/arch/ia64/kernel/smp.c	2005-08-23 10:51:04.769473645 -0400
@@ -53,6 +53,7 @@
  * requirements. It also looks cleaner.
  */
 static  __cacheline_aligned DEFINE_SPINLOCK(call_lock);
+static spinlock_t dump_call_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
 
 struct call_data_struct {
 	void (*func) (void *info);
@@ -63,6 +64,7 @@ struct call_data_struct {
 };
 
 static volatile struct call_data_struct *call_data;
+static volatile struct call_data_struct *saved_call_data;
 
 #define IPI_CALL_FUNC		0
 #define IPI_CPU_STOP		1
@@ -306,6 +308,48 @@ smp_call_function_single (int cpuid, voi
 EXPORT_SYMBOL(smp_call_function_single);
 
 /*
+ * dump version of smp_call_function to avoid deadlock in call_lock
+ */
+void dump_smp_call_function (void (*func) (void *info), void *info)
+{
+	static struct call_data_struct dumpdata;
+	int waitcount;
+
+	spin_lock(&dump_call_lock);
+	/* if another cpu beat us, they win! */
+	if (dumpdata.func) {
+		spin_unlock(&dump_call_lock);
+		func(info);
+		/* NOTREACHED */
+	}
+
+	/* freeze call_lock or wait for on-going IPIs to settle down */
+	waitcount = 0;
+	while (!spin_trylock(&call_lock)) {
+		if (waitcount++ > 1000) {
+			/* save original for dump analysis */
+			saved_call_data = call_data;
+			break;
+		}
+		udelay(1000);
+		cpu_relax();
+	}
+
+	dumpdata.func = func;
+	dumpdata.info = info;
+	dumpdata.wait = 0; /* not used */
+	atomic_set(&dumpdata.started, 0); /* not used */
+	atomic_set(&dumpdata.finished, 0); /* not used */
+
+	call_data = &dumpdata;
+	mb();
+	send_IPI_allbutself(IPI_CALL_FUNC);
+	/* Don't wait */
+	spin_unlock(&dump_call_lock);
+}
+EXPORT_SYMBOL(dump_smp_call_function);
+
+/*
  * this function sends a 'generic call function' IPI to all other CPUs
  * in the system.
  */
--- linux-2.6.12/arch/powerpc/kernel/smp.c.orig	2005-08-23 10:49:53.005279633 -0400
+++ linux-2.6.12/arch/powerpc/kernel/smp.c	2005-08-23 10:51:04.770473481 -0400
@@ -200,6 +200,7 @@ void smp_send_stop(void)
  * Stolen from the i386 version.
  */
 static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock);
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(dump_call_lock);
 
 static struct call_data_struct {
 	void (*func) (void *info);
@@ -207,12 +208,54 @@ static struct call_data_struct {
 	atomic_t started;
 	atomic_t finished;
 	int wait;
-} *call_data;
+} *call_data, *saved_call_data;
 
 /* delay of at least 8 seconds */
 #define SMP_CALL_TIMEOUT	8
 
 /*
+ * dump version of smp_call_function to avoid deadlock in call_lock
+ */
+void dump_smp_call_function (void (*func) (void *info), void *info)
+{
+	static struct call_data_struct dumpdata;
+	int waitcount;
+
+	spin_lock(&dump_call_lock);
+	/* if another cpu beat us, they win! */
+	if (dumpdata.func) {
+		spin_unlock(&dump_call_lock);
+		func(info);
+		/* NOTREACHED */
+	}
+
+	/* freeze call_lock or wait for on-going IPIs to settle down */
+	waitcount = 0;
+	while (!spin_trylock(&call_lock)) {
+		if (waitcount++ > 1000) {
+			/* save original for dump analysis */
+			saved_call_data = call_data;
+			break;
+		}
+		udelay(1000);
+		barrier();
+	}
+	dumpdata.func = func;
+	dumpdata.info = info;
+	dumpdata.wait = 0; /* not used */
+	atomic_set(&dumpdata.started, 0); /* not used */
+	atomic_set(&dumpdata.finished, 0); /* not used */
+
+	call_data = &dumpdata;
+	wmb();
+	smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION);
+	/* Don't wait */
+	spin_unlock(&dump_call_lock);
+}
+
+EXPORT_SYMBOL(dump_smp_call_function);
+
+/*
  * This function sends a 'generic call function' IPI to all other CPUs
  * in the system.
  *
--- linux-2.6.12/arch/i386/kernel/smp.c.orig	2005-08-23 10:50:15.380598925 -0400
+++ linux-2.6.12/arch/i386/kernel/smp.c	2005-08-23 10:53:29.712621271 -0400
@@ -489,6 +489,7 @@ void smp_send_reschedule(int cpu)
  * static memory requirements. It also looks cleaner.
  */
 static DEFINE_SPINLOCK(call_lock);
+static DEFINE_SPINLOCK(dump_call_lock);
 
 struct call_data_struct {
 	void (*func) (void *info);
@@ -509,6 +510,49 @@ void unlock_ipi_call_lock(void)
 }
 
 static struct call_data_struct * call_data;
+static struct call_data_struct * saved_call_data;
+
+/*
+ * dump version of smp_call_function to avoid deadlock in call_lock
+ */
+void dump_smp_call_function (void (*func) (void *info), void *info)
+{
+	static struct call_data_struct dumpdata;
+	int waitcount;
+
+	spin_lock(&dump_call_lock);
+	/* if another cpu beat us, they win! */
+	if (dumpdata.func) {
+		spin_unlock(&dump_call_lock);
+		func(info);
+		/* NOTREACHED */
+	}
+	/* freeze call_lock or wait for on-going IPIs to settle down */
+	waitcount = 0;
+	while (!spin_trylock(&call_lock)) {
+		if (waitcount++ > 1000) {
+			/* save original for dump analysis */
+			saved_call_data = call_data;
+			break;
+		}
+		udelay(1000);
+		barrier();
+	}
+
+	dumpdata.func = func;
+	dumpdata.info = info;
+	dumpdata.wait = 0; /* not used */
+	atomic_set(&dumpdata.started, 0); /* not used */
+	atomic_set(&dumpdata.finished, 0); /* not used */
+
+	call_data = &dumpdata;
+	mb();
+	send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+	/* Don't wait */
+	spin_unlock(&dump_call_lock);
+}
+
+EXPORT_SYMBOL(dump_smp_call_function);
 
 /*
  * this function sends a 'generic call function' IPI to all other CPUs
--- linux-2.6.12/arch/x86_64/kernel/smp.c.orig	2005-08-23 10:49:53.421211215 -0400
+++ linux-2.6.12/arch/x86_64/kernel/smp.c	2005-08-23 10:51:04.771473316 -0400
@@ -20,6 +20,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/mc146818rtc.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 
 #include <asm/mtrr.h>
 #include <asm/pgalloc.h>
@@ -271,6 +271,7 @@ void smp_send_reschedule(int cpu)
  * static memory requirements. It also looks cleaner.
  */
 static DEFINE_SPINLOCK(call_lock);
+static DEFINE_SPINLOCK(dump_call_lock);
 
 struct call_data_struct {
 	void (*func) (void *info);
@@ -281,6 +282,49 @@ struct call_data_struct {
 };
 
 static struct call_data_struct * call_data;
+static struct call_data_struct * saved_call_data;
+
+/*
+ * dump version of smp_call_function to avoid deadlock in call_lock
+ */
+void dump_smp_call_function (void (*func) (void *info), void *info)
+{
+	static struct call_data_struct dumpdata;
+	int waitcount;
+
+	spin_lock(&dump_call_lock);
+	/* if another cpu beat us, they win! */
+	if (dumpdata.func) {
+		spin_unlock(&dump_call_lock);
+		func(info);
+		/* NOTREACHED */
+	}
+
+ 	/* freeze call_lock or wait for on-going IPIs to settle down */
+	waitcount = 0;
+	while (!spin_trylock(&call_lock)) {
+		if (waitcount++ > 1000) {
+			/* save original for dump analysis */
+			saved_call_data = call_data;
+			break;
+		}
+		udelay(1000);
+		barrier();
+	}
+
+	dumpdata.func = func;
+	dumpdata.info = info;
+	dumpdata.wait = 0; /* not used */
+	atomic_set(&dumpdata.started, 0); /* not used */
+	atomic_set(&dumpdata.finished, 0); /* not used */
+
+ 	call_data = &dumpdata;
+	wmb();
+	send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+	/* Don't wait */
+	spin_unlock(&dump_call_lock);
+}
+EXPORT_SYMBOL(dump_smp_call_function);
 
 void lock_ipi_call_lock(void)
 {
--- linux-2.6.12/drivers/block/diskdump.c.orig	2005-08-23 10:50:16.489416520 -0400
+++ linux-2.6.12/drivers/block/diskdump.c	2005-08-23 10:51:04.773472987 -0400
@@ -456,7 +456,7 @@ static void freeze_other_cpus(void)
 #if CONFIG_SMP
 	int	i;
 
-	smp_call_function(freeze_cpu, NULL, 1, -1);
+	dump_smp_call_function(freeze_cpu, NULL);
 	diskdump_mdelay(3000);
 	printk("CPU frozen: ");
 	for (i = 0; i < NR_CPUS; i++) {
--- linux-2.6.12/drivers/net/netdump.c.orig	2005-08-23 10:50:16.449423099 -0400
+++ linux-2.6.12/drivers/net/netdump.c	2005-08-23 10:51:04.774472823 -0400
@@ -356,7 +356,7 @@ static void netpoll_start_netdump(struct
 	local_irq_save(flags);
 	preempt_disable();
 
-	smp_call_function(freeze_cpu, NULL, 1, -1);
+	dump_smp_call_function(freeze_cpu, NULL);
 	netdump_mdelay(3000);
 	for (i = 0; i < NR_CPUS; i++) {
 		if (cpus_frozen[i])
--- linux-2.6.12/include/linux/smp.h.orig	2005-08-23 10:50:08.023809136 -0400
+++ linux-2.6.12/include/linux/smp.h	2005-08-23 10:51:04.775472658 -0400
@@ -55,6 +55,7 @@ extern void smp_cpus_done(unsigned int m
  */
 extern int smp_call_function (void (*func) (void *info), void *info,
 			      int retry, int wait);
+extern void dump_smp_call_function (void (*func) (void *info), void *info);
 
 /*
  * Call a function on all processors
@@ -95,6 +96,7 @@ void smp_prepare_boot_cpu(void);
 #define raw_smp_processor_id()			0
 #define hard_smp_processor_id()			0
 #define smp_call_function(func,info,retry,wait)	({ 0; })
+static inline void dump_smp_call_function(void (*func) (void *info), void *info) { }
 #define on_each_cpu(func,info,retry,wait)	({ func(info); 0; })
 static inline void smp_send_reschedule(int cpu) { }
 #define num_booting_cpus()			1

linux-2.6-execshield-vdso.patch:
 arch/i386/kernel/sysenter.c |   70 ++++++++++++++++++++++++---------------
 fs/binfmt_elf.c             |   15 ++------
 fs/proc/task_mmu.c          |    9 +++--
 include/asm-i386/elf.h      |    7 +++
 include/asm-i386/page.h     |    5 ++
 include/linux/mm.h          |    5 ++
 kernel/sysctl.c             |   10 +++++
 mm/mmap.c                   |   78 ++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 159 insertions(+), 40 deletions(-)

--- NEW FILE linux-2.6-execshield-vdso.patch ---
--- linux-2.6.13/include/asm-i386/page.h.vdso
+++ linux-2.6.13/include/asm-i386/page.h
@@ -120,6 +120,11 @@ extern int devmem_is_allowed(unsigned lo
 #endif
 #define __KERNEL_START		(__PAGE_OFFSET + __PHYSICAL_START)
 
+/*
+ * Under exec-shield we don't use the generic fixmap gate area.
+ * The vDSO ("gate area") has a normal vma found the normal ways.
+ */
+#define __HAVE_ARCH_GATE_AREA	1
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
--- linux-2.6.13/include/asm-i386/elf.h.vdso
+++ linux-2.6.13/include/asm-i386/elf.h
@@ -146,6 +146,12 @@ do {									\
 	}								\
 } while (0)
 
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+				       int executable_stack);
+
+#if 0	/* Disabled for exec-shield, where a normal vma holds the vDSO.  */
 /*
  * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
  * extra segments containing the vsyscall DSO contents.  Dumping its
@@ -189,6 +195,7 @@ do {									      \
 				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
 	}								      \
 } while (0)
+#endif
 
 #endif
 
--- linux-2.6.13/include/linux/mm.h.vdso
+++ linux-2.6.13/include/linux/mm.h
@@ -848,6 +848,11 @@ static inline unsigned long get_unmapped
 	return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0);	
 }
 
+extern int install_special_mapping(struct mm_struct *mm,
+				   unsigned long addr, unsigned long len,
+				   unsigned long vm_flags, pgprot_t pgprot,
+				   struct page **pages);
+
 extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
 	unsigned long len, unsigned long prot,
 	unsigned long flag, unsigned long pgoff);
--- linux-2.6.13/fs/binfmt_elf.c.vdso
+++ linux-2.6.13/fs/binfmt_elf.c
@@ -1001,8 +1001,6 @@ static int load_elf_binary(struct linux_
 		elf_entry = loc->elf_ex.e_entry;
 	}
 
-	kfree(elf_phdata);
-
 	if (interpreter_type != INTERPRETER_AOUT)
 		sys_close(elf_exec_fileno);
 
@@ -1012,17 +1010,11 @@ static int load_elf_binary(struct linux_
 	retval = arch_setup_additional_pages(bprm, executable_stack);
 	if (retval < 0) {
 		send_sig(SIGKILL, current, 0);
-		goto out;
+		goto out_free_fh;
 	}
 #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
 
-	/*
-	 * Map the vsyscall trampoline. This address is then passed via
-	 * AT_SYSINFO.
-	 */
-#ifdef __HAVE_ARCH_VSYSCALL
-	map_vsyscall();
-#endif
+	kfree(elf_phdata);
 
 	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
@@ -1227,6 +1219,9 @@ static int maydump(struct vm_area_struct
 	if (vma->vm_flags & (VM_IO | VM_RESERVED))
 		return 0;
 
+	if (vma->vm_flags & VM_DONTEXPAND) /* Kludge for vDSO.  */
+		return 1;
+
 	/* Dump shared memory only if mapped from an anonymous file.  */
 	if (vma->vm_flags & VM_SHARED)
 		return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
--- linux-2.6.13/fs/proc/task_mmu.c.vdso
+++ linux-2.6.13/fs/proc/task_mmu.c
@@ -156,14 +156,19 @@ static int show_map_internal(struct seq_
 			if (vma->vm_end == mm->brk) {
 				pad_len_spaces(m, len);
 				seq_puts(m, "[heap]");
-			} else {
-				if (vma->vm_start <= mm->start_stack &&
+			} else if (vma->vm_start <= mm->start_stack &&
 					vma->vm_end >= mm->start_stack) {
 
 					pad_len_spaces(m, len);
 					seq_puts(m, "[stack]");
 				}
+#ifdef __i386__
+			else if (vma->vm_start ==
+				(unsigned long)mm->context.vdso) {
+				pad_len_spaces(m, len);
+				seq_puts(m, "[vdso]");
 			}
+#endif
 		} else {
 			pad_len_spaces(m, len);
 			seq_puts(m, "[vdso]");
--- linux-2.6.13/mm/mmap.c.vdso
+++ linux-2.6.13/mm/mmap.c
@@ -2155,3 +2155,81 @@ int may_expand_vm(struct mm_struct *mm, 
 		return 0;
 	return 1;
 }
+
+
+static struct page *
+special_mapping_nopage(struct vm_area_struct *vma,
+		       unsigned long address, int *type)
+{
+	struct page **pages;
+
+	BUG_ON(address < vma->vm_start || address >= vma->vm_end);
+
+	address -= vma->vm_start;
+	for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
+		address -= PAGE_SIZE;
+
+	if (*pages) {
+		get_page(*pages);
+		return *pages;
+	}
+
+	return NOPAGE_SIGBUS;
+}
+
+static struct vm_operations_struct special_mapping_vmops = {
+	.nopage	= special_mapping_nopage,
+};
+
+unsigned int vdso_populate = 1;
+
+/*
+ * Insert a new vma covering the given region, with the given flags and
+ * protections.  Its pages are supplied by the given null-terminated array.
+ * The region past the last page supplied will always produce SIGBUS.
+ * The array pointer and the pages it points to are assumed to stay alive
+ * for as long as this mapping might exist.
+ */
+int install_special_mapping(struct mm_struct *mm,
+			    unsigned long addr, unsigned long len,
+			    unsigned long vm_flags, pgprot_t pgprot,
+			    struct page **pages)
+{
+	struct vm_area_struct *vma;
+	int err;
+
+	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (unlikely(vma == NULL))
+		return -ENOMEM;
+	memset(vma, 0, sizeof(*vma));
+
+	vma->vm_mm = mm;
+	vma->vm_start = addr;
+	vma->vm_end = addr + len;
+
+	vma->vm_flags = vm_flags;
+	vma->vm_page_prot = pgprot;
+
+	vma->vm_ops = &special_mapping_vmops;
+	vma->vm_private_data = pages;
+
+	insert_vm_struct(mm, vma);
+	mm->total_vm += len >> PAGE_SHIFT;
+
+	if (!vdso_populate)
+		return 0;
+
+	err = 0;
+	while (*pages) {
+		struct page *page = *pages++;
+		get_page(page);
+		err = install_page(mm, vma, addr, page, vma->vm_page_prot);
+		if (err) {
+			put_page(page);
+			break;
+		}
+		addr += PAGE_SIZE;
+	}
+
+	return err;
+}
--- linux-2.6.13/arch/i386/kernel/sysenter.c.vdso
+++ linux-2.6.13/arch/i386/kernel/sysenter.c
@@ -47,20 +47,13 @@ void enable_sep_cpu(void)
 extern const char vsyscall_int80_start, vsyscall_int80_end;
 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
 
-struct page *sysenter_page;
+static struct page *sysenter_pages[2];
 
 int __init sysenter_setup(void)
 {
 	void *page = (void *)get_zeroed_page(GFP_ATOMIC);
 
-	/*
-	 * We keep this page mapped readonly, even though the executable
-	 * portion is randomized into a userspace vma - so that we dont
-	 * have to fix up the data within the VDSO page every time we
-	 * exec().
-	 */
-	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_KERNEL_RO);
-	sysenter_page = virt_to_page(page);
+	sysenter_pages[0] = virt_to_page(page);
 
 	if (!boot_cpu_has(X86_FEATURE_SEP)) {
 		memcpy(page,
@@ -78,37 +71,60 @@ int __init sysenter_setup(void)
 
 extern void SYSENTER_RETURN_OFFSET;
 
-unsigned int vdso_enabled = 0;
+unsigned int vdso_enabled = 1;
 
-void map_vsyscall(void)
+/*
+ * This is called from binfmt_elf, we create the special vma for the
+ * vDSO and insert it into the mm struct tree.
+ */
+int arch_setup_additional_pages(struct linux_binprm *bprm,
+				int executable_stack)
 {
 	struct thread_info *ti = current_thread_info();
-	struct vm_area_struct *vma;
-	unsigned long addr;
+	unsigned long addr, len;
+	int err;
 
-	if (unlikely(!vdso_enabled)) {
 		current->mm->context.vdso = NULL;
-		return;
-	}
+	if (unlikely(!vdso_enabled) || unlikely(!sysenter_pages[0]))
+		return 0;
 
 	/*
 	 * Map the vDSO (it will be randomized):
 	 */
 	down_write(&current->mm->mmap_sem);
-	addr = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, 0);
-	current->mm->context.vdso = (void *)addr;
-	ti->sysenter_return = (void *)addr + (long)&SYSENTER_RETURN_OFFSET;
-	if (addr != -1) {
-		vma = find_vma(current->mm, addr);
-		if (vma) {
-			pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
-			get_page(sysenter_page);
-			install_page(current->mm, vma, addr,
-					sysenter_page, vma->vm_page_prot);
-			
+	len = PAGE_SIZE > ELF_EXEC_PAGESIZE ? PAGE_SIZE : ELF_EXEC_PAGESIZE;
+	addr = get_unmapped_area_prot(NULL, 0, len, 0,
+				      MAP_PRIVATE, PROT_READ | PROT_EXEC);
+	if (unlikely(addr & ~PAGE_MASK)) {
+		up_write(&current->mm->mmap_sem);
+		return addr;
 		}
+	err = install_special_mapping(current->mm, addr, len,
+				      VM_DONTEXPAND | VM_READ | VM_EXEC |
+				      VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+				      PAGE_READONLY_EXEC,
+				      sysenter_pages);
+	if (likely(err == 0)) {
+		current->mm->context.vdso = (void *)addr;
+		ti->sysenter_return = &SYSENTER_RETURN_OFFSET + addr;
 	}
 	up_write(&current->mm->mmap_sem);
+	return err;
+}
+
+int in_gate_area_no_task(unsigned long addr)
+{
+	return 0;
+}
+
+int in_gate_area(struct task_struct *task, unsigned long addr)
+{
+	return 0;
+}
+
+struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
+{
+	return NULL;
 }
 
 static int __init vdso_setup(char *str)
--- linux-2.6.13/kernel/sysctl.c
+++ linux-2.6.13/kernel/sysctl.c
@@ -74,7 +74,7 @@ extern int proc_unknown_nmi_panic(ctl_ta
 				  void __user *, size_t *, loff_t *);
 #endif
 
-extern unsigned int vdso_enabled;
+extern unsigned int vdso_enabled, vdso_populate;
 
 int exec_shield = 1;
 
@@ -316,6 +316,14 @@ static ctl_table kern_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
+	{
+		.ctl_name	= KERN_VDSO,
+		.procname	= "vdso_populate",
+		.data		= &vdso_populate,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 #endif
 	{
 		.ctl_name	= KERN_CORE_USES_PID,


linux-2.6-execshield-xen.patch:
 arch/i386/xen/kernel/entry.S              |    8 +-
 arch/i386/xen/kernel/process.c            |   58 ++++++++++++++++++
 arch/i386/xen/kernel/smp.c                |    2 
 arch/i386/xen/kernel/traps.c              |   93 +++++++++++++++++++++++++++++-
 arch/i386/xen/mm/init.c                   |   11 ++-
 include/asm-i386/mach-xen/asm/desc.h      |   14 ++++
 include/asm-i386/mach-xen/asm/mmu.h       |    2 
 include/asm-i386/mach-xen/asm/processor.h |    6 +
 8 files changed, 187 insertions(+), 7 deletions(-)

--- NEW FILE linux-2.6-execshield-xen.patch ---
Merge rawhide execshield diffs into xen subarch
---

 arch/i386/xen/kernel/entry.S              |    8 ++
 arch/i386/xen/kernel/process.c            |   58 ++++++++++++++++++
 arch/i386/xen/kernel/smp.c                |    2 +
 arch/i386/xen/kernel/traps.c              |   93 ++++++++++++++++++++++++++++-
 arch/i386/xen/mm/init.c                   |   11 +++
 include/asm-i386/mach-xen/asm/desc.h      |   14 ++++
 include/asm-i386/mach-xen/asm/mmu.h       |    2 +
 include/asm-i386/mach-xen/asm/processor.h |    6 ++
 8 files changed, 187 insertions(+), 7 deletions(-)

diff --git a/arch/i386/xen/kernel/entry.S b/arch/i386/xen/kernel/entry.S
index 8e71c50..ced2bb8 100644
--- a/arch/i386/xen/kernel/entry.S
+++ b/arch/i386/xen/kernel/entry.S
@@ -233,8 +233,12 @@ sysenter_past_esp:
 	pushl %ebp
 	pushfl
 	pushl $(__USER_CS)
-	pushl $SYSENTER_RETURN
-
+	/*
+	 * Push current_thread_info()->sysenter_return to the stack.
+	 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
+	 * pushed above; +8 corresponds to copy_thread's esp0 setting.
+	 */
+	pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
 /*
  * Load the potential sixth argument from user stack.
  * Careful about security.
diff --git a/arch/i386/xen/kernel/process.c b/arch/i386/xen/kernel/process.c
index 55be738..dbd41a1 100644
--- a/arch/i386/xen/kernel/process.c
+++ b/arch/i386/xen/kernel/process.c
@@ -543,6 +543,8 @@ struct task_struct fastcall * __switch_t
 #if 0 /* lazy fpu sanity check */
 	else BUG_ON(!(read_cr0() & 8));
 #endif
+	if (next_p->mm)
+		load_user_cs_desc(cpu, next_p->mm);
 
 	/*
 	 * Reload esp0.
@@ -835,3 +837,59 @@ unsigned long arch_align_stack(unsigned 
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_add_exec_range(struct mm_struct *mm, unsigned long limit)
+{
+	if (limit > mm->context.exec_limit) {
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end)
+{
+	struct vm_area_struct *vma;
+	unsigned long limit = PAGE_SIZE;
+
+	if (old_end == mm->context.exec_limit) {
+		for (vma = mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_flush_exec_range(struct mm_struct *mm)
+{
+	mm->context.exec_limit = 0;
+	set_user_cs(&mm->context.user_cs, 0);
+}
+
+/*
+ * Generate random brk address between 128MB and 196MB. (if the layout
+ * allows it.)
+ */
+void randomize_brk(unsigned long old_brk)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = 0x08000000;
+	if (current->mm->brk >= range_start)
+		range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = new_brk;
+}
+
diff --git a/arch/i386/xen/kernel/smp.c b/arch/i386/xen/kernel/smp.c
index 855e088..230200c 100644
--- a/arch/i386/xen/kernel/smp.c
+++ b/arch/i386/xen/kernel/smp.c
@@ -277,6 +277,8 @@ irqreturn_t smp_invalidate_interrupt(int
 	unsigned long cpu;
 
 	cpu = get_cpu();
+	if (current->active_mm)
+		load_user_cs_desc(cpu, current->active_mm);
 
 	if (!cpu_isset(cpu, flush_cpumask))
 		goto out;
diff --git a/arch/i386/xen/kernel/traps.c b/arch/i386/xen/kernel/traps.c
index 0f7199b..878c084 100644
--- a/arch/i386/xen/kernel/traps.c
+++ b/arch/i386/xen/kernel/traps.c
@@ -459,11 +459,89 @@ DO_ERROR_INFO(17, SIGBUS, "alignment che
 #ifdef CONFIG_X86_MCE
 DO_ERROR(18, SIGBUS, "machine check", machine_check)
 #endif
-DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
+
+
+/*
+ * lazy-check for CS validity on exec-shield binaries:
+ *
+ * the original non-exec stack patch was written by
+ * Solar Designer <solar at openwall.com>. Thanks!
+ */
+static int
+check_lazy_exec_limit(int cpu, struct pt_regs *regs, long error_code)
+{
+	struct desc_struct *desc1, *desc2;
+	struct vm_area_struct *vma;
+	unsigned long limit;
+
+	if (current->mm == NULL)
+		return 0;
+
+	limit = -1UL;
+	if (current->mm->context.exec_limit != -1UL) {
+		limit = PAGE_SIZE;
+		spin_lock(&current->mm->page_table_lock);
+		for (vma = current->mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+		spin_unlock(&current->mm->page_table_lock);
+		if (limit >= TASK_SIZE)
+			limit = -1UL;
+		current->mm->context.exec_limit = limit;
+	}
+	set_user_cs(&current->mm->context.user_cs, limit);
+
+	desc1 = &current->mm->context.user_cs;
+	desc2 = &get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS];
+
+	if (desc1->a != desc2->a || desc1->b != desc2->b) {
+		/*
+		 * The CS was not in sync - reload it and retry the
+		 * instruction. If the instruction still faults then
+		 * we won't hit this branch next time around.
+		 */
+		if (print_fatal_signals >= 2) {
+			printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+			printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
+		}
+		load_user_cs_desc(cpu, current->mm);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * The fixup code for errors in iret jumps to here (iret_exc).  It loses
+ * the original trap number and error code.  The bogus trap 32 and error
+ * code 0 are what the vanilla kernel delivers via:
+ * DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
+ *
+ * In case of a general protection fault in the iret instruction, we
+ * need to check for a lazy CS update for exec-shield.
+ */
+fastcall void do_iret_error(struct pt_regs *regs, long error_code)
+{
+	int ok = check_lazy_exec_limit(get_cpu(), regs, error_code);
+	put_cpu();
+	if (!ok && notify_die(DIE_TRAP, "iret exception", regs,
+			      error_code, 32, SIGSEGV) != NOTIFY_STOP) {
+		siginfo_t info;
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		info.si_code = ILL_BADSTK;
+		info.si_addr = 0;
+		do_trap(32, SIGSEGV, "iret exception", 0, regs, error_code,
+			&info);
+	}
+}
 
 fastcall void __kprobes do_general_protection(struct pt_regs * regs,
 					      long error_code)
 {
+	int cpu = get_cpu();
+	int ok;
+
 	/*
 	 * If we trapped on an LDT access then ensure that the default_ldt is
 	 * loaded, if nothing else. We load default_ldt lazily because LDT
@@ -473,13 +551,22 @@ fastcall void __kprobes do_general_prote
 		unsigned long ldt;
 		__asm__ __volatile__ ("sldt %0" : "=r" (ldt));
 		if (ldt == 0) {
+			put_cpu();
 			xen_set_ldt((unsigned long)&default_ldt[0], 5);
 			return;
 		}
 	}
 
-	current->thread.error_code = error_code;
-	current->thread.trap_no = 13;
+	ok = check_lazy_exec_limit(cpu, regs, error_code);
+	put_cpu();
+
+	if (ok)
+		return;
+
+	if (print_fatal_signals) {
+		printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+		printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
+	}
 
 	if (regs->eflags & VM_MASK)
 		goto gp_in_vm86;
diff --git a/arch/i386/xen/mm/init.c b/arch/i386/xen/mm/init.c
index f243508..4c8c7ac 100644
--- a/arch/i386/xen/mm/init.c
+++ b/arch/i386/xen/mm/init.c
@@ -274,7 +274,10 @@ int page_is_ram(unsigned long pagenr)
 #else /* CONFIG_XEN */
 
 #define page_kills_ppro(p)	0
-#define page_is_ram(p)		1
+int page_is_ram(unsigned long pagenr)
+{
+	return 1;
+}
 
 #endif
 
@@ -469,7 +472,7 @@ u64 __supported_pte_mask __read_mostly =
  * Control non executable mappings.
  *
  * on      Enable
- * off     Disable
+ * off     Disable (disables exec-shield too)
  */
 void __init noexec_setup(const char *str)
 {
@@ -479,6 +482,7 @@ void __init noexec_setup(const char *str
 	} else if (!strncmp(str,"off",3)) {
 		disable_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
+		exec_shield = 0;
 	}
 }
 
@@ -547,7 +551,10 @@ void __init paging_init(void)
 	set_nx();
 	if (nx_enabled)
 		printk("NX (Execute Disable) protection: active\n");
+	else
 #endif
+	if (exec_shield)
+		printk("Using x86 segment limits to approximate NX protection\n");
 
 	pagetable_init();
 
diff --git a/include/asm-i386/mach-xen/asm/desc.h b/include/asm-i386/mach-xen/asm/desc.h
index 864ace7..019fc22 100644
--- a/include/asm-i386/mach-xen/asm/desc.h
+++ b/include/asm-i386/mach-xen/asm/desc.h
@@ -159,6 +159,20 @@ static inline unsigned long get_desc_bas
 	return base;
 }
 
+static inline void set_user_cs(struct desc_struct *desc, unsigned long limit)
+{
+	limit = (limit - 1) / PAGE_SIZE;
+	desc->a = limit & 0xffff;
+	desc->b = (limit & 0xf0000) | 0x00c0fb00;
+}
+
+#define load_user_cs_desc(cpu, mm) \
+	HYPERVISOR_update_descriptor(virt_to_machine(&get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS]), (u64)(mm)->context.user_cs.a | ((u64)(mm)->context.user_cs.b) << 32); 
+
+extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_flush_exec_range(struct mm_struct *mm);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif
diff --git a/include/asm-i386/mach-xen/asm/mmu.h b/include/asm-i386/mach-xen/asm/mmu.h
index c646692..b103653 100644
--- a/include/asm-i386/mach-xen/asm/mmu.h
+++ b/include/asm-i386/mach-xen/asm/mmu.h
@@ -12,6 +12,8 @@ typedef struct { 
 	int size;
 	struct semaphore sem;
 	void *ldt;
+	struct desc_struct user_cs;
+	unsigned long exec_limit;
 	void *vdso;
 } mm_context_t;
 
diff --git a/include/asm-i386/mach-xen/asm/processor.h b/include/asm-i386/mach-xen/asm/processor.h
index 070ff44..5b7ca04 100644
--- a/include/asm-i386/mach-xen/asm/processor.h
+++ b/include/asm-i386/mach-xen/asm/processor.h
@@ -332,6 +332,9 @@ extern int bootloader_type;
  */
 #define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
 
+#define __HAVE_ARCH_ALIGN_STACK
+extern unsigned long arch_align_stack(unsigned long sp);
+
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
 /*
@@ -513,6 +516,9 @@ static inline void load_esp0(struct tss_
 	regs->xcs = __USER_CS;					\
 	regs->eip = new_eip;					\
 	regs->esp = new_esp;					\
+	preempt_disable();					\
+	load_user_cs_desc(smp_processor_id(), current->mm);	\
+	preempt_enable();					\
 } while (0)
 
 /*

linux-2.6-execshield.patch:
 linux-2.6.13-a/arch/x86_64/ia32/ia32_binfmt.c  |    4 
 linux-2.6.13-a/arch/x86_64/kernel/process.c    |    6 -
 linux-2.6.13-a/arch/x86_64/kernel/setup64.c    |   25 -----
 linux-2.6.13-a/include/asm-x86_64/pgtable.h    |    2 
 linux-2.6.13/mm/fremap.c                       |   16 +--
 linux-810/arch/i386/kernel/asm-offsets.c       |    1 
 linux-810/arch/i386/kernel/entry.S             |    8 +
 linux-810/arch/i386/kernel/process.c           |   59 ++++++++++++
 linux-810/arch/i386/kernel/signal.c            |    4 
 linux-810/arch/i386/kernel/smp.c               |    3 
 linux-810/arch/i386/kernel/sysenter.c          |   55 +++++++++++
 linux-810/arch/i386/kernel/traps.c             |   93 ++++++++++++++++++-
 linux-810/arch/i386/kernel/vsyscall-sysenter.S |    6 -
 linux-810/arch/i386/kernel/vsyscall.lds.S      |    4 
 linux-810/arch/i386/mm/init.c                  |    6 +
 linux-810/arch/i386/mm/mmap.c                  |    6 -
 linux-810/arch/ia64/ia32/binfmt_elf32.c        |    2 
 linux-810/arch/x86_64/ia32/ia32_binfmt.c       |    2 
 linux-810/arch/x86_64/kernel/process.c         |    7 -
 linux-810/arch/x86_64/mm/Makefile              |    2 
 linux-810/arch/x86_64/mm/fault.c               |    2 
 linux-810/arch/x86_64/mm/mmap.c                |   95 +++++++++++++++++++
 linux-810/drivers/char/random.c                |    7 +
 linux-810/fs/binfmt_elf.c                      |  120 ++++++++++++++++++++-----
 linux-810/fs/proc/array.c                      |    8 +
 linux-810/fs/proc/base.c                       |    4 
 linux-810/fs/proc/task_mmu.c                   |   25 ++++-
 linux-810/include/asm-i386/desc.h              |   14 ++
 linux-810/include/asm-i386/elf.h               |   42 +++++---
 linux-810/include/asm-i386/mmu.h               |    6 +
 linux-810/include/asm-i386/pgalloc.h           |    1 
 linux-810/include/asm-i386/processor.h         |    8 +
 linux-810/include/asm-i386/thread_info.h       |    1 
 linux-810/include/asm-ia64/pgalloc.h           |    4 
 linux-810/include/asm-powerpc/pgalloc.h        |    5 +
 linux-810/include/asm-ppc/pgalloc.h            |    5 +
 linux-810/include/asm-s390/pgalloc.h           |    4 
 linux-810/include/asm-sparc/pgalloc.h          |    4 
 linux-810/include/asm-sparc64/pgalloc.h        |    4 
 linux-810/include/asm-x86_64/pgalloc.h         |    7 +
 linux-810/include/asm-x86_64/processor.h       |    5 +
 linux-810/include/linux/mm.h                   |    9 +
 linux-810/include/linux/resource.h             |    5 -
 linux-810/include/linux/sched.h                |    9 +
 linux-810/include/linux/sysctl.h               |    3 
 linux-810/kernel/signal.c                      |   38 +++++++
 linux-810/kernel/sysctl.c                      |   39 ++++++++
 linux-810/mm/mmap.c                            |  105 ++++++++++++++++++++-
 linux-810/mm/mprotect.c                        |    5 -
 linux-810/mm/mremap.c                          |    4 
 linux-813/arch/i386/kernel/cpu/common.c        |    7 +
 51 files changed, 780 insertions(+), 126 deletions(-)

--- NEW FILE linux-2.6-execshield.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/asm-offsets.c linux-810/arch/i386/kernel/asm-offsets.c
--- linux-804/arch/i386/kernel/asm-offsets.c
+++ linux-810/arch/i386/kernel/asm-offsets.c
@@ -53,6 +53,7 @@ void foo(void)
 	OFFSET(TI_preempt_count, thread_info, preempt_count);
 	OFFSET(TI_addr_limit, thread_info, addr_limit);
 	OFFSET(TI_restart_block, thread_info, restart_block);
+	OFFSET(TI_sysenter_return, thread_info, sysenter_return);
 	BLANK();
 
 	OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/entry.S linux-810/arch/i386/kernel/entry.S
--- linux-804/arch/i386/kernel/entry.S
+++ linux-810/arch/i386/kernel/entry.S
@@ -184,8 +184,12 @@ sysenter_past_esp:
 	pushl %ebp
 	pushfl
 	pushl $(__USER_CS)
-	pushl $SYSENTER_RETURN
-
+	/*
+	 * Push current_thread_info()->sysenter_return to the stack.
+	 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
+	 * pushed above; +8 corresponds to copy_thread's esp0 setting.
+	 */
+	pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
 /*
  * Load the potential sixth argument from user stack.
  * Careful about security.
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/process.c linux-810/arch/i386/kernel/process.c
--- linux-804/arch/i386/kernel/process.c
+++ linux-810/arch/i386/kernel/process.c
@@ -676,6 +676,8 @@ struct task_struct fastcall * __switch_t
 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
 	__unlazy_fpu(prev_p);
+	if (next_p->mm)
+		load_user_cs_desc(cpu, next_p->mm);
 
 	/*
 	 * Reload esp0.
@@ -949,3 +951,60 @@ unsigned long arch_align_stack(unsigned 
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_add_exec_range(struct mm_struct *mm, unsigned long limit)
+{
+	if (limit > mm->context.exec_limit) {
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end)
+{
+	struct vm_area_struct *vma;
+	unsigned long limit = PAGE_SIZE;
+
+	if (old_end == mm->context.exec_limit) {
+		for (vma = mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_flush_exec_range(struct mm_struct *mm)
+{
+	mm->context.exec_limit = 0;
+	set_user_cs(&mm->context.user_cs, 0);
+}
+
+/*
+ * Generate random brk address between 128MB and 196MB. (if the layout
+ * allows it.)
+ */
+void randomize_brk(unsigned long old_brk)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = 0x08000000;
+	if (current->mm->brk >= range_start)
+		range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = new_brk;
+}
+
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/signal.c linux-810/arch/i386/kernel/signal.c
--- linux-804/arch/i386/kernel/signal.c
+++ linux-810/arch/i386/kernel/signal.c
@@ -380,7 +380,7 @@ static int setup_frame(int sig, struct k
 			goto give_sigsegv;
 	}
 
-	restorer = &__kernel_sigreturn;
+	restorer = current->mm->context.vdso + (long)&__kernel_sigreturn;
 	if (ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 
@@ -476,7 +476,7 @@ static int setup_rt_frame(int sig, struc
 		goto give_sigsegv;
 
 	/* Set up to return from userspace.  */
-	restorer = &__kernel_rt_sigreturn;
+	restorer = current->mm->context.vdso + (long)&__kernel_rt_sigreturn;
 	if (ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 	err |= __put_user(restorer, &frame->pretcode);
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/smp.c linux-810/arch/i386/kernel/smp.c
--- linux-804/arch/i386/kernel/smp.c
+++ linux-810/arch/i386/kernel/smp.c
@@ -24,6 +24,7 @@
 
 #include <asm/mtrr.h>
 #include <asm/tlbflush.h>
+#include <asm/desc.h>
 #include <mach_apic.h>
 
 /*
@@ -315,6 +316,8 @@ fastcall void smp_invalidate_interrupt(s
 	unsigned long cpu;
 
 	cpu = get_cpu();
+	if (current->active_mm)
+		load_user_cs_desc(cpu, current->active_mm);
 
 	if (!cpu_isset(cpu, flush_cpumask))
 		goto out;
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/sysenter.c linux-810/arch/i386/kernel/sysenter.c
--- linux-804/arch/i386/kernel/sysenter.c
+++ linux-810/arch/i386/kernel/sysenter.c
@@ -13,6 +13,7 @@
 #include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/elf.h>
+#include <linux/mman.h>
 
 #include <asm/cpufeature.h>
 #include <asm/msr.h>
@@ -46,11 +47,20 @@ void enable_sep_cpu(void)
 extern const char vsyscall_int80_start, vsyscall_int80_end;
 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
 
+struct page *sysenter_page;
+
 int __init sysenter_setup(void)
 {
 	void *page = (void *)get_zeroed_page(GFP_ATOMIC);
 
-	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
+	/*
+	 * We keep this page mapped readonly, even though the executable
+	 * portion is randomized into a userspace vma - so that we dont
+	 * have to fix up the data within the VDSO page every time we
+	 * exec().
+	 */
+	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_KERNEL_RO);
+	sysenter_page = virt_to_page(page);
 
 	if (!boot_cpu_has(X86_FEATURE_SEP)) {
 		memcpy(page,
@@ -65,3 +75,46 @@ int __init sysenter_setup(void)
 
 	return 0;
 }
+
+extern void SYSENTER_RETURN_OFFSET;
+
+unsigned int vdso_enabled = 0;
+
+void map_vsyscall(void)
+{
+	struct thread_info *ti = current_thread_info();
+	struct vm_area_struct *vma;
+	unsigned long addr;
+
+	if (unlikely(!vdso_enabled)) {
+		current->mm->context.vdso = NULL;
+		return;
+	}
+
+	/*
+	 * Map the vDSO (it will be randomized):
+	 */
+	down_write(&current->mm->mmap_sem);
+	addr = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, 0);
+	current->mm->context.vdso = (void *)addr;
+	ti->sysenter_return = (void *)addr + (long)&SYSENTER_RETURN_OFFSET;
+	if (addr != -1) {
+		vma = find_vma(current->mm, addr);
+		if (vma) {
+			pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+			get_page(sysenter_page);
+			install_page(current->mm, vma, addr,
+					sysenter_page, vma->vm_page_prot);
+			
+		}
+	}
+	up_write(&current->mm->mmap_sem);
+}
+
+static int __init vdso_setup(char *str)
+{
+        vdso_enabled = simple_strtoul(str, NULL, 0);
+        return 1;
+}
+__setup("vdso=", vdso_setup);
+
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/traps.c linux-810/arch/i386/kernel/traps.c
--- linux-804/arch/i386/kernel/traps.c
+++ linux-810/arch/i386/kernel/traps.c
@@ -458,13 +458,89 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", inv
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
-DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
+
+
+/*
+ * lazy-check for CS validity on exec-shield binaries:
+ *
+ * the original non-exec stack patch was written by
+ * Solar Designer <solar at openwall.com>. Thanks!
+ */
+static int
+check_lazy_exec_limit(int cpu, struct pt_regs *regs, long error_code)
+{
+	struct desc_struct *desc1, *desc2;
+	struct vm_area_struct *vma;
+	unsigned long limit;
+
+	if (current->mm == NULL)
+		return 0;
+
+	limit = -1UL;
+	if (current->mm->context.exec_limit != -1UL) {
+		limit = PAGE_SIZE;
+		spin_lock(&current->mm->page_table_lock);
+		for (vma = current->mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+		spin_unlock(&current->mm->page_table_lock);
+		if (limit >= TASK_SIZE)
+			limit = -1UL;
+		current->mm->context.exec_limit = limit;
+	}
+	set_user_cs(&current->mm->context.user_cs, limit);
+
+	desc1 = &current->mm->context.user_cs;
+	desc2 = per_cpu(cpu_gdt_table, cpu) + GDT_ENTRY_DEFAULT_USER_CS;
+
+	if (desc1->a != desc2->a || desc1->b != desc2->b) {
+		/*
+		 * The CS was not in sync - reload it and retry the
+		 * instruction. If the instruction still faults then
+		 * we won't hit this branch next time around.
+		 */
+		if (print_fatal_signals >= 2) {
+			printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+			printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
+		}
+		load_user_cs_desc(cpu, current->mm);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * The fixup code for errors in iret jumps to here (iret_exc).  It loses
+ * the original trap number and error code.  The bogus trap 32 and error
+ * code 0 are what the vanilla kernel delivers via:
+ * DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
+ *
+ * In case of a general protection fault in the iret instruction, we
+ * need to check for a lazy CS update for exec-shield.
+ */
+fastcall void do_iret_error(struct pt_regs *regs, long error_code)
+{
+	int ok = check_lazy_exec_limit(get_cpu(), regs, error_code);
+	put_cpu();
+	if (!ok && notify_die(DIE_TRAP, "iret exception", regs,
+			      error_code, 32, SIGSEGV) != NOTIFY_STOP) {
+		siginfo_t info;
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		info.si_code = ILL_BADSTK;
+		info.si_addr = 0;
+		do_trap(32, SIGSEGV, "iret exception", 0, regs, error_code,
+			&info);
+	}
+}
 
 fastcall void __kprobes do_general_protection(struct pt_regs * regs,
 					      long error_code)
 {
 	int cpu = get_cpu();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
 	struct thread_struct *thread = &current->thread;
+	int ok;
 
 	/*
@@ -490,7 +566,6 @@ fastcall void do_general_protection(stru
 		put_cpu();
 		return;
 	}
-	put_cpu();
 
 	current->thread.error_code = error_code;
 	current->thread.trap_no = 13;
@@ -501,17 +576,31 @@ fastcall void do_general_protection(stru
 	if (!user_mode(regs))
 		goto gp_in_kernel;
 
+	ok = check_lazy_exec_limit(cpu, regs, error_code);
+
+	put_cpu();
+
+	if (ok)
+		return;
+
+	if (print_fatal_signals) {
+		printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+		printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
+	}
+
 	current->thread.error_code = error_code;
 	current->thread.trap_no = 13;
 	force_sig(SIGSEGV, current);
 	return;
 
 gp_in_vm86:
+	put_cpu();
 	local_irq_enable();
 	handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
 	return;
 
 gp_in_kernel:
+	put_cpu();
 	if (!fixup_exception(regs)) {
 		if (notify_die(DIE_GPF, "general protection fault", regs,
 				error_code, 13, SIGSEGV) == NOTIFY_STOP)
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/vsyscall.lds.S linux-810/arch/i386/kernel/vsyscall.lds.S
--- linux-804/arch/i386/kernel/vsyscall.lds.S
+++ linux-810/arch/i386/kernel/vsyscall.lds.S
@@ -7,7 +7,7 @@
 
 SECTIONS
 {
-  . = VSYSCALL_BASE + SIZEOF_HEADERS;
+  . = SIZEOF_HEADERS;
 
   .hash           : { *(.hash) }		:text
   .dynsym         : { *(.dynsym) }
@@ -20,7 +20,7 @@ SECTIONS
      For the layouts to match, we need to skip more than enough
      space for the dynamic symbol table et al.  If this amount
      is insufficient, ld -shared will barf.  Just increase it here.  */
-  . = VSYSCALL_BASE + 0x400;
+  . = 0x400;
 
   .text           : { *(.text) }		:text =0x90909090
   .note		  : { *(.note.*) }		:text :note
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/kernel/vsyscall-sysenter.S linux-810/arch/i386/kernel/vsyscall-sysenter.S
--- linux-804/arch/i386/kernel/vsyscall-sysenter.S
+++ linux-810/arch/i386/kernel/vsyscall-sysenter.S
@@ -24,11 +24,11 @@ __kernel_vsyscall:
 	/* 7: align return point with nop's to make disassembly easier */
 	.space 7,0x90
 
-	/* 14: System call restart point is here! (SYSENTER_RETURN - 2) */
+	/* 14: System call restart point is here! (SYSENTER_RETURN_OFFSET-2) */
 	jmp .Lenter_kernel
 	/* 16: System call normal return point is here! */
-	.globl SYSENTER_RETURN	/* Symbol used by entry.S.  */
-SYSENTER_RETURN:
+	.globl SYSENTER_RETURN_OFFSET	/* Symbol used by sysenter.c  */
+SYSENTER_RETURN_OFFSET:
 	pop %ebp
 .Lpop_ebp:
 	pop %edx
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/mm/init.c linux-810/arch/i386/mm/init.c
--- linux-804/arch/i386/mm/init.c
+++ linux-810/arch/i386/mm/init.c
@@ -401,7 +401,7 @@ u64 __supported_pte_mask = ~_PAGE_NX;
  * Control non executable mappings.
  *
  * on      Enable
- * off     Disable
+ * off     Disable (disables exec-shield too)
  */
 void __init noexec_setup(const char *str)
 {
@@ -411,6 +411,7 @@ void __init noexec_setup(const char *str
 	} else if (!strncmp(str,"off",3)) {
 		disable_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
+		exec_shield = 0;
 	}
 }
 
@@ -475,7 +476,10 @@ void __init paging_init(void)
 	set_nx();
 	if (nx_enabled)
 		printk("NX (Execute Disable) protection: active\n");
+	else
 #endif
+	if (exec_shield)
+		printk("Using x86 segment limits to approximate NX protection\n");
 
 	pagetable_init();
 
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/i386/mm/mmap.c linux-810/arch/i386/mm/mmap.c
--- linux-804/arch/i386/mm/mmap.c
+++ linux-810/arch/i386/mm/mmap.c
@@ -62,15 +62,17 @@ void arch_pick_mmap_layout(struct mm_str
 	 * Fall back to the standard layout if the personality
 	 * bit is set, or if the expected stack growth is unlimited:
 	 */
-	if (sysctl_legacy_va_layout ||
+	if ((exec_shield != 2) && (sysctl_legacy_va_layout ||
 			(current->personality & ADDR_COMPAT_LAYOUT) ||
-			current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
+			current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)) {
 		mm->mmap_base = TASK_UNMAPPED_BASE;
 		mm->get_unmapped_area = arch_get_unmapped_area;
 		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base(mm);
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		if (!(current->personality & READ_IMPLIES_EXEC))
+			mm->get_unmapped_exec_area = arch_get_unmapped_exec_area;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/ia64/ia32/binfmt_elf32.c linux-810/arch/ia64/ia32/binfmt_elf32.c
--- linux-804/arch/ia64/ia32/binfmt_elf32.c
+++ linux-810/arch/ia64/ia32/binfmt_elf32.c
@@ -272,7 +272,7 @@ elf32_set_personality (void)
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
 {
 	unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
 
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/x86_64/ia32/ia32_binfmt.c linux-810/arch/x86_64/ia32/ia32_binfmt.c
--- linux-804/arch/x86_64/ia32/ia32_binfmt.c
+++ linux-810/arch/x86_64/ia32/ia32_binfmt.c
@@ -396,7 +396,7 @@ int setup_arg_pages(struct linux_binprm 
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
 {
 	unsigned long map_addr;
 	struct task_struct *me = current; 
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/x86_64/kernel/process.c linux-810/arch/x86_64/kernel/process.c
--- linux-804/arch/x86_64/kernel/process.c
+++ linux-810/arch/x86_64/kernel/process.c
@@ -833,10 +833,3 @@ int dump_task_regs(struct task_struct *t
  
 	return 1;
 }
-
-unsigned long arch_align_stack(unsigned long sp)
-{
-	if (randomize_va_space)
-		sp -= get_random_int() % 8192;
-	return sp & ~0xf;
-}
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/x86_64/mm/fault.c linux-810/arch/x86_64/mm/fault.c
--- linux-804/arch/x86_64/mm/fault.c
+++ linux-810/arch/x86_64/mm/fault.c
@@ -73,7 +73,7 @@ static noinline int is_prefetch(struct p
 	instr = (unsigned char *)convert_rip_to_linear(current, regs);
 	max_instr = instr + 15;
 
-	if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
+	if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE64)
 		return 0;
 
 	while (scan_more && instr < max_instr) { 
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/x86_64/mm/Makefile linux-810/arch/x86_64/mm/Makefile
--- linux-804/arch/x86_64/mm/Makefile
+++ linux-810/arch/x86_64/mm/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the linux x86_64-specific parts of the memory manager.
 #
 
-obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
+obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o mmap.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_NUMA) += numa.o
 obj-$(CONFIG_K8_NUMA) += k8topology.o
diff -urNp --exclude-from=/home/davej/.exclude linux-804/arch/x86_64/mm/mmap.c linux-810/arch/x86_64/mm/mmap.c
--- linux-804/arch/x86_64/mm/mmap.c
+++ linux-810/arch/x86_64/mm/mmap.c
@@ -0,0 +1,95 @@
+/*
+ *  linux/arch/x86-64/mm/mmap.c
+ *
+ *  flexible mmap layout support
+ *
+ * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * Started by Ingo Molnar <mingo at elte.hu>
+ */
+
+#include <linux/personality.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+
+/*
+ * Top of mmap area (just below the process stack).
+ *
+ * Leave an at least ~128 MB hole.
+ */
+#define MIN_GAP (128*1024*1024)
+#define MAX_GAP (TASK_SIZE/6*5)
+
+static inline unsigned long mmap_base(void)
+{
+	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+
+	if (gap < MIN_GAP)
+		gap = MIN_GAP;
+	else if (gap > MAX_GAP)
+		gap = MAX_GAP;
+
+	return TASK_SIZE - (gap & PAGE_MASK);
+}
+
+static inline int mmap_is_legacy(void)
+{
+	/*
+	 * Force standard allocation for 64 bit programs.
+	 */
+	if (!test_thread_flag(TIF_IA32))
+		return 1;
+		
+	if (current->personality & ADDR_COMPAT_LAYOUT) 
+		return 1;
+	
+	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+		return 1;
+		
+	return sysctl_legacy_va_layout;
+}
+
+/*
+ * This function, called very early during the creation of a new
+ * process VM image, sets up which VM layout function to use:
+ */
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+	/*
+	 * Fall back to the standard layout if the personality
+	 * bit is set, or if the expected stack growth is unlimited:
+	 */
+	if (mmap_is_legacy()) {
+		mm->mmap_base = TASK_UNMAPPED_BASE;
+		mm->get_unmapped_area = arch_get_unmapped_area;
+		mm->unmap_area = arch_unmap_area;
+	} else {
+		mm->mmap_base = mmap_base();
+		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		mm->unmap_area = arch_unmap_area_topdown;
+	}
+}
+
+unsigned long arch_align_stack(unsigned long sp)
+{
+	if (current->flags & PF_RANDOMIZE)
+		sp -= get_random_int() % 8192;
+	return sp & ~0xf;
+}
+
diff -urNp --exclude-from=/home/davej/.exclude linux-804/drivers/char/random.c linux-810/drivers/char/random.c
--- linux-804/drivers/char/random.c
+++ linux-810/drivers/char/random.c
@@ -1634,13 +1634,18 @@ EXPORT_SYMBOL(secure_dccp_sequence_numbe
  */
 unsigned int get_random_int(void)
 {
+	unsigned int val = 0;
+
+#ifdef CONFIG_X86_HAS_TSC
+	rdtscl(val);
+#endif
 	/*
 	 * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
 	 * every second, from the entropy pool (and thus creates a limited
 	 * drain on it), and uses halfMD4Transform within the second. We
 	 * also mix it with jiffies and the PID:
 	 */
-	return secure_ip_id(current->pid + jiffies);
+	return secure_ip_id(current->pid + jiffies + (int)val);
 }
 
 /*
diff -urNp --exclude-from=/home/davej/.exclude linux-804/fs/binfmt_elf.c linux-810/fs/binfmt_elf.c
--- linux-804/fs/binfmt_elf.c
+++ linux-810/fs/binfmt_elf.c
@@ -47,7 +47,7 @@
 
 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
 static int load_elf_library(struct file*);
-static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
+static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long);
 extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
 
 #ifndef elf_addr_t
@@ -285,20 +285,59 @@ create_elf_tables(struct linux_binprm *b
 #ifndef elf_map
 
 static unsigned long elf_map(struct file *filep, unsigned long addr,
-			struct elf_phdr *eppnt, int prot, int type)
+			     struct elf_phdr *eppnt, int prot, int type,
+			     unsigned long total_size)
 {
 	unsigned long map_addr;
+	unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
+	unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
+
+	addr = ELF_PAGESTART(addr);
+	size = ELF_PAGEALIGN(size);
 
 	down_write(&current->mm->mmap_sem);
-	map_addr = do_mmap(filep, ELF_PAGESTART(addr),
-			   eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
-			   eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
+
+	/*
+	 * total_size is the size of the ELF (interpreter) image.
+	 * The _first_ mmap needs to know the full size, otherwise
+	 * randomization might put this image into an overlapping
+	 * position with the ELF binary image. (since size < total_size)
+	 * So we first map the 'big' image - and unmap the remainder at
+	 * the end. (which unmap is needed for ELF images with holes.)
+	 */
+	if (total_size) {
+		total_size = ELF_PAGEALIGN(total_size);
+		map_addr = do_mmap(filep, addr, total_size, prot, type, off);
+		if (!BAD_ADDR(map_addr))
+			do_munmap(current->mm, map_addr+size, total_size-size);
+	} else
+		map_addr = do_mmap(filep, addr, size, prot, type, off);
+		
 	up_write(&current->mm->mmap_sem);
-	return(map_addr);
+
+	return map_addr;
 }
 
 #endif /* !elf_map */
 
+static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
+{
+	int i, first_idx = -1, last_idx = -1;
+
+	for (i = 0; i < nr; i++)
+		if (cmds[i].p_type == PT_LOAD) {
+			last_idx = i;
+			if (first_idx == -1)
+				first_idx = i;
+		}
+
+	if (first_idx == -1)
+		return 0;
+
+	return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz -
+				ELF_PAGESTART(cmds[first_idx].p_vaddr);
+}
+
 /* This is much more generalized than the library routine read function,
    so we keep this separate.  Technically the library read function
    is only provided so that we can read a.out libraries that have
@@ -306,7 +345,8 @@ static unsigned long elf_map(struct file
 
 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
 				     struct file * interpreter,
-				     unsigned long *interp_load_addr)
+				     unsigned long *interp_load_addr,
+				     unsigned long no_base)
 {
 	struct elf_phdr *elf_phdata;
 	struct elf_phdr *eppnt;
@@ -314,6 +354,7 @@ static unsigned long load_elf_interp(str
 	int load_addr_set = 0;
 	unsigned long last_bss = 0, elf_bss = 0;
 	unsigned long error = ~0UL;
+	unsigned long total_size;
 	int retval, i, size;
 
 	/* First of all, some simple consistency checks */
@@ -352,6 +393,10 @@ static unsigned long load_elf_interp(str
 		goto out_close;
 	}
 
+	total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
+	if (!total_size)
+		goto out_close;
+
 	eppnt = elf_phdata;
 	for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
 	  if (eppnt->p_type == PT_LOAD) {
@@ -366,8 +411,11 @@ static unsigned long load_elf_interp(str
 	    vaddr = eppnt->p_vaddr;
 	    if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
 	    	elf_type |= MAP_FIXED;
+	    else if (no_base && interp_elf_ex->e_type == ET_DYN)
+		load_addr = -vaddr;
 
-	    map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
+	    map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type, total_size);
+	    total_size = 0;
 	    error = map_addr;
 	    if (BAD_ADDR(map_addr))
 	    	goto out_close;
@@ -527,7 +575,7 @@ static int load_elf_binary(struct linux_
 	unsigned long reloc_func_desc = 0;
 	char passed_fileno[6];
 	struct files_struct *files;
-	int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT;
+	int have_pt_gnu_stack, executable_stack;
 	unsigned long def_flags = 0;
 	struct {
 		struct elfhdr elf_ex;
@@ -683,6 +731,8 @@ static int load_elf_binary(struct linux_
 	}
 
 	elf_ppnt = elf_phdata;
+	executable_stack = EXSTACK_DEFAULT;
+
 	for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)
 		if (elf_ppnt->p_type == PT_GNU_STACK) {
 			if (elf_ppnt->p_flags & PF_X)
@@ -693,6 +743,11 @@ static int load_elf_binary(struct linux_
 		}
 	have_pt_gnu_stack = (i < loc->elf_ex.e_phnum);
 
+	if (current->personality == PER_LINUX && exec_shield == 2) {
+		executable_stack = EXSTACK_DISABLE_X;
+		current->flags |= PF_RANDOMIZE;
+	}
+
 	/* Some simple consistency checks for the interpreter */
 	if (elf_interpreter) {
 		interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
@@ -746,6 +801,15 @@ static int load_elf_binary(struct linux_
 	if (retval)
 		goto out_free_dentry;
 
+#ifdef __i386__
+	/*
+	 * Turn off the CS limit completely if exec-shield disabled or
+	 * NX active:
+	 */
+	if (!exec_shield || executable_stack != EXSTACK_DISABLE_X || nx_enabled)
+		arch_add_exec_range(current->mm, -1);
+#endif
+
 	/* Discard our unneeded old files struct */
 	if (files) {
 		steal_locks(files);
@@ -764,7 +828,8 @@ static int load_elf_binary(struct linux_
 	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
 	   may depend on the personality.  */
 	SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
-	if (elf_read_implies_exec(loc->elf_ex, executable_stack))
+	if (exec_shield != 2 &&
+			elf_read_implies_exec(loc->elf_ex, executable_stack))
 		current->personality |= READ_IMPLIES_EXEC;
 
 	if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
@@ -785,10 +850,10 @@ static int load_elf_binary(struct linux_
 	
 	current->mm->start_stack = bprm->p;
 
+
 	/* Now we do a little grungy work by mmaping the ELF image into
-	   the correct location in memory.  At this point, we assume that
-	   the image should be loaded at fixed address, not at a variable
-	   address. */
+	   the correct location in memory.
+	 */
 
 	for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
 		int elf_prot = 0, elf_flags;
@@ -832,16 +897,16 @@ static int load_elf_binary(struct linux_
 		elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
 
 		vaddr = elf_ppnt->p_vaddr;
-		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
+		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set)
 			elf_flags |= MAP_FIXED;
-		} else if (loc->elf_ex.e_type == ET_DYN) {
-			/* Try and get dynamic programs out of the way of the default mmap
-			   base, as well as whatever program they might try to exec.  This
-			   is because the brk will follow the loader, and is not movable.  */
+		else if (loc->elf_ex.e_type == ET_DYN)
+#ifdef __i386__
+			load_bias = 0;
+#else
 			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-		}
+#endif
 
-		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
+		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags, 0);
 		if (BAD_ADDR(error)) {
 			send_sig(SIGKILL, current, 0);
 			goto out_free_dentry;
@@ -918,7 +983,8 @@ static int load_elf_binary(struct linux_
 		else
 			elf_entry = load_elf_interp(&loc->interp_elf_ex,
 						    interpreter,
-						    &interp_load_addr);
+						    &interp_load_addr,
+						    load_bias);
 		if (BAD_ADDR(elf_entry)) {
 			printk(KERN_ERR "Unable to load interpreter %.128s\n",
 				elf_interpreter);
@@ -950,6 +1016,14 @@ static int load_elf_binary(struct linux_
 	}
 #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
 
+	/*
+	 * Map the vsyscall trampoline. This address is then passed via
+	 * AT_SYSINFO.
+	 */
+#ifdef __HAVE_ARCH_VSYSCALL
+	map_vsyscall();
+#endif
+
 	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
 	create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT),
@@ -963,6 +1037,10 @@ static int load_elf_binary(struct linux_
 	current->mm->end_data = end_data;
 	current->mm->start_stack = bprm->p;
 
+#ifdef __HAVE_ARCH_RANDOMIZE_BRK
+	if (current->flags & PF_RANDOMIZE)
+		randomize_brk(elf_brk);
+#endif
 	if (current->personality & MMAP_PAGE_ZERO) {
 		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
 		   and some applications "depend" upon this behavior.
diff -urNp --exclude-from=/home/davej/.exclude linux-804/fs/proc/array.c linux-810/fs/proc/array.c
--- linux-804/fs/proc/array.c
+++ linux-810/fs/proc/array.c
@@ -385,8 +385,12 @@ static int do_task_stat(struct task_stru
 	ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
 	read_unlock(&tasklist_lock);
 
-	if (!whole || num_threads<2)
-		wchan = get_wchan(task);
+	if (!whole || num_threads<2) {
+		wchan = 0;
+		if (current->uid == task->uid || current->euid == task->uid ||
+				capable(CAP_SYS_NICE))
+			wchan = get_wchan(task);
+	}
 	if (!whole) {
 		min_flt = task->min_flt;
 		maj_flt = task->maj_flt;
diff -urNp --exclude-from=/home/davej/.exclude linux-804/fs/proc/base.c linux-810/fs/proc/base.c
--- linux-804/fs/proc/base.c
+++ linux-810/fs/proc/base.c
@@ -181,7 +181,7 @@ static struct pid_entry tgid_base_stuff[
 	E(PROC_TGID_CMDLINE,   "cmdline", S_IFREG|S_IRUGO),
 	E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
 	E(PROC_TGID_STATM,     "statm",   S_IFREG|S_IRUGO),
-	E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUGO),
+	E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUSR),
 #ifdef CONFIG_NUMA
 	E(PROC_TGID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
 #endif
@@ -221,7 +221,7 @@ static struct pid_entry tid_base_stuff[]
 	E(PROC_TID_CMDLINE,    "cmdline", S_IFREG|S_IRUGO),
 	E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
 	E(PROC_TID_STATM,      "statm",   S_IFREG|S_IRUGO),
-	E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUGO),
+	E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUSR),
 #ifdef CONFIG_NUMA
 	E(PROC_TID_NUMA_MAPS,  "numa_maps",    S_IFREG|S_IRUGO),
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-804/fs/proc/task_mmu.c linux-810/fs/proc/task_mmu.c
--- linux-804/fs/proc/task_mmu.c
+++ linux-810/fs/proc/task_mmu.c
@@ -43,7 +43,11 @@ char *task_mem(struct mm_struct *mm, cha
 		"VmStk:\t%8lu kB\n"
 		"VmExe:\t%8lu kB\n"
 		"VmLib:\t%8lu kB\n"
-		"VmPTE:\t%8lu kB\n",
+		"VmPTE:\t%8lu kB\n"
+		"StaBrk:\t%08lx kB\n"
+		"Brk:\t%08lx kB\n"
+		"StaStk:\t%08lx kB\n"
+		,
 		hiwater_vm << (PAGE_SHIFT-10),
 		(total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
 		mm->locked_vm << (PAGE_SHIFT-10),
@@ -51,7 +55,13 @@ char *task_mem(struct mm_struct *mm, cha
 		total_rss << (PAGE_SHIFT-10),
 		data << (PAGE_SHIFT-10),
 		mm->stack_vm << (PAGE_SHIFT-10), text, lib,
-		(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
+		(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
+		mm->start_brk, mm->brk, mm->start_stack);
+#ifdef __i386__
+	if (!nx_enabled)
+		buffer += sprintf(buffer,
+			"ExecLim:\t%08lx\n", mm->context.exec_limit);
+#endif
 	return buffer;
 }
 
@@ -123,7 +133,13 @@ static int show_map_internal(struct seq_
 			vma->vm_end,
 			flags & VM_READ ? 'r' : '-',
 			flags & VM_WRITE ? 'w' : '-',
-			flags & VM_EXEC ? 'x' : '-',
+			(flags & VM_EXEC
+#ifdef __i386__
+				|| (!nx_enabled &&
+				(vma->vm_start < task->mm->context.exec_limit))
+#endif
+			)
+				? 'x' : '-',
 			flags & VM_MAYSHARE ? 's' : 'p',
 			vma->vm_pgoff << PAGE_SHIFT,
 			MAJOR(dev), MINOR(dev), ino, &len);
@@ -137,8 +153,7 @@ static int show_map_internal(struct seq_
 		seq_path(m, file->f_vfsmnt, file->f_dentry, "\n");
 	} else {
 		if (mm) {
-			if (vma->vm_start <= mm->start_brk &&
-						vma->vm_end >= mm->brk) {
+			if (vma->vm_end == mm->brk) {
 				pad_len_spaces(m, len);
 				seq_puts(m, "[heap]");
 			} else {
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-i386/desc.h linux-810/include/asm-i386/desc.h
--- linux-804/include/asm-i386/desc.h
+++ linux-810/include/asm-i386/desc.h
@@ -156,6 +156,20 @@ static inline unsigned long get_desc_bas
 	return base;
 }
 
+static inline void set_user_cs(struct desc_struct *desc, unsigned long limit)
+{
+	limit = (limit - 1) / PAGE_SIZE;
+	desc->a = limit & 0xffff;
+	desc->b = (limit & 0xf0000) | 0x00c0fb00;
+}
+
+#define load_user_cs_desc(cpu, mm) \
+    	per_cpu(cpu_gdt_table, (cpu))[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs
+
+extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_flush_exec_range(struct mm_struct *mm);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-i386/elf.h linux-810/include/asm-i386/elf.h
--- linux-804/include/asm-i386/elf.h
+++ linux-810/include/asm-i386/elf.h
@@ -9,6 +9,7 @@
 #include <asm/user.h>
 #include <asm/processor.h>
 #include <asm/system.h>		/* for savesegment */
 #include <asm/auxvec.h>
+#include <asm/desc.h>
 
 #include <linux/utsname.h>
@@ -133,15 +134,22 @@ extern int dump_task_extended_fpu (struc
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
 
-#define VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
-#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
-#define VSYSCALL_ENTRY	((unsigned long) &__kernel_vsyscall)
 extern void __kernel_vsyscall;
+#define VSYSCALL_BASE	((unsigned long)current->mm->context.vdso)
+#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
+#define VSYSCALL_OFFSET	((unsigned long) &__kernel_vsyscall)
+#define VSYSCALL_ENTRY	(VSYSCALL_BASE + VSYSCALL_OFFSET)
 
-#define ARCH_DLINFO						\
-do {								\
-		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);	\
-		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);	\
+/* kernel-internal fixmap address: */
+#define __VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
+#define __VSYSCALL_EHDR	((const struct elfhdr *) __VSYSCALL_BASE)
+
+#define ARCH_DLINFO							\
+do {									\
+	if (VSYSCALL_BASE) {						\
+		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);		\
+		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);		\
+	}								\
 } while (0)
 
 /*
@@ -152,15 +160,15 @@ do {								\
  * Dumping its extra ELF program headers includes all the other information
  * a debugger needs to easily find how the vsyscall DSO was being used.
  */
-#define ELF_CORE_EXTRA_PHDRS		(VSYSCALL_EHDR->e_phnum)
+#define ELF_CORE_EXTRA_PHDRS		(__VSYSCALL_EHDR->e_phnum)
 #define ELF_CORE_WRITE_EXTRA_PHDRS					      \
 do {									      \
 	const struct elf_phdr *const vsyscall_phdrs =			      \
-		(const struct elf_phdr *) (VSYSCALL_BASE		      \
-					   + VSYSCALL_EHDR->e_phoff);	      \
+		(const struct elf_phdr *) (__VSYSCALL_BASE		      \
+					   + __VSYSCALL_EHDR->e_phoff);	      \
 	int i;								      \
 	Elf32_Off ofs = 0;						      \
-	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+	for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) {		      \
 		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
 		if (phdr.p_type == PT_LOAD) {				      \
 			BUG_ON(ofs != 0);				      \
@@ -178,10 +186,10 @@ do {									      \
 #define ELF_CORE_WRITE_EXTRA_DATA					      \
 do {									      \
 	const struct elf_phdr *const vsyscall_phdrs =			      \
-		(const struct elf_phdr *) (VSYSCALL_BASE		      \
-					   + VSYSCALL_EHDR->e_phoff);	      \
+		(const struct elf_phdr *) (__VSYSCALL_BASE		      \
+					   + __VSYSCALL_EHDR->e_phoff);	      \
 	int i;								      \
-	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+	for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) {		      \
 		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
 			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
 				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
@@ -190,4 +198,10 @@ do {									      \
 
 #endif
 
+#define __HAVE_ARCH_RANDOMIZE_BRK
+extern void randomize_brk(unsigned long old_brk);
+
+#define __HAVE_ARCH_VSYSCALL
+extern void map_vsyscall(void);
+
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-i386/mmu.h linux-810/include/asm-i386/mmu.h
--- linux-804/include/asm-i386/mmu.h
+++ linux-810/include/asm-i386/mmu.h
@@ -7,11 +7,17 @@
  * we put the segment information here.
  *
  * cpu_vm_mask is used to optimize ldt flushing.
+ *
+ * exec_limit is used to track the range PROT_EXEC
+ * mappings span.
  */
 typedef struct { 
 	int size;
 	struct semaphore sem;
 	void *ldt;
+	struct desc_struct user_cs;
+	unsigned long exec_limit;
+	void *vdso;
 } mm_context_t;
 
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-i386/pgalloc.h linux-810/include/asm-i386/pgalloc.h
--- linux-804/include/asm-i386/pgalloc.h
+++ linux-810/include/asm-i386/pgalloc.h
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <asm/fixmap.h>
+#include <asm/desc.h>
 #include <linux/threads.h>
 #include <linux/mm.h>		/* for struct page */
 
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-i386/processor.h linux-810/include/asm-i386/processor.h
--- linux-804/include/asm-i386/processor.h
+++ linux-810/include/asm-i386/processor.h
@@ -317,7 +317,10 @@ extern int bootloader_type;
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
+#define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE/3)
+
+#define __HAVE_ARCH_ALIGN_STACK
+extern unsigned long arch_align_stack(unsigned long sp);
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
@@ -499,6 +502,9 @@ static inline void load_esp0(struct tss_
 	regs->xcs = __USER_CS;					\
 	regs->eip = new_eip;					\
 	regs->esp = new_esp;					\
+	preempt_disable();					\
+	load_user_cs_desc(smp_processor_id(), current->mm);	\
+	preempt_enable();					\
 } while (0)
 
 /*
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-i386/thread_info.h linux-810/include/asm-i386/thread_info.h
--- linux-804/include/asm-i386/thread_info.h
+++ linux-810/include/asm-i386/thread_info.h
@@ -38,6 +38,7 @@ struct thread_info {
 					 	   0-0xBFFFFFFF for user-thead
 						   0-0xFFFFFFFF for kernel-thread
 						*/
+	void			*sysenter_return;
 	struct restart_block    restart_block;
 
 	unsigned long           previous_esp;   /* ESP of the previous stack in case
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-ia64/pgalloc.h linux-810/include/asm-ia64/pgalloc.h
--- linux-804/include/asm-ia64/pgalloc.h
+++ linux-810/include/asm-ia64/pgalloc.h
@@ -1,6 +1,10 @@
 #ifndef _ASM_IA64_PGALLOC_H
 #define _ASM_IA64_PGALLOC_H
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 /*
  * This file contains the functions and defines necessary to allocate
  * page tables.
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-ppc/pgalloc.h linux-810/include/asm-ppc/pgalloc.h
--- linux-804/include/asm-ppc/pgalloc.h
+++ linux-810/include/asm-ppc/pgalloc.h
@@ -40,5 +40,10 @@ extern void pte_free(struct page *pte);
 
 #define check_pgt_cache()	do { } while (0)
 
+#define arch_add_exec_range(mm, limit)         do { ; } while (0)
+#define arch_flush_exec_range(mm)              do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)      do { ; } while (0)
+
+
 #endif /* _PPC_PGALLOC_H */
 #endif /* __KERNEL__ */
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-powerpc/pgalloc.h linux-810/include/asm-powerpc/pgalloc.h
--- linux-804/include/asm-powerpc/pgalloc.h
+++ linux-810/include/asm-powerpc/pgalloc.h
@@ -13,6 +13,11 @@ extern kmem_cache_t *pgtable_cache[];
 #define PUD_CACHE_NUM	1
 #define PGD_CACHE_NUM	0
 
+/* Dummy functions since we don't support execshield on ppc */
+#define arch_add_exec_range(mm, limit) do { ; } while (0)
+#define arch_flush_exec_range(mm)      do { ; } while (0)
+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
+
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-s390/pgalloc.h linux-810/include/asm-s390/pgalloc.h
--- linux-804/include/asm-s390/pgalloc.h
+++ linux-810/include/asm-s390/pgalloc.h
@@ -18,6 +18,10 @@
 #include <linux/gfp.h>
 #include <linux/mm.h>
 
+#define arch_add_exec_range(mm, limit) do { ; } while (0)
+#define arch_flush_exec_range(mm)      do { ; } while (0)
+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
+
 #define check_pgt_cache()	do {} while (0)
 
 extern void diag10(unsigned long addr);
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-sparc/pgalloc.h linux-810/include/asm-sparc/pgalloc.h
--- linux-804/include/asm-sparc/pgalloc.h
+++ linux-810/include/asm-sparc/pgalloc.h
@@ -66,4 +66,8 @@ BTFIXUPDEF_CALL(void, pte_free, struct p
 #define pte_free(pte)		BTFIXUP_CALL(pte_free)(pte)
 #define __pte_free_tlb(tlb, pte)	pte_free(pte)
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 #endif /* _SPARC_PGALLOC_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-sparc64/pgalloc.h linux-810/include/asm-sparc64/pgalloc.h
--- linux-804/include/asm-sparc64/pgalloc.h
+++ linux-810/include/asm-sparc64/pgalloc.h
@@ -180,4 +180,8 @@ static inline void pte_free(struct page 
 #define pgd_free(pgd)		free_pgd_fast(pgd)
 #define pgd_alloc(mm)		get_pgd_fast()
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 #endif /* _SPARC64_PGALLOC_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-x86_64/pgalloc.h linux-810/include/asm-x86_64/pgalloc.h
--- linux-804/include/asm-x86_64/pgalloc.h
+++ linux-810/include/asm-x86_64/pgalloc.h
@@ -6,6 +6,13 @@
 #include <linux/threads.h>
 #include <linux/mm.h>
 
+#define arch_add_exec_range(mm, limit) \
+		do { (void)(mm), (void)(limit); } while (0)
+#define arch_flush_exec_range(mm) \
+		do { (void)(mm); } while (0)
+#define arch_remove_exec_range(mm, limit) \
+		do { (void)(mm), (void)(limit); } while (0)
+
 #define pmd_populate_kernel(mm, pmd, pte) \
 		set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
 #define pud_populate(mm, pud, pmd) \
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/asm-x86_64/processor.h linux-810/include/asm-x86_64/processor.h
--- linux-804/include/asm-x86_64/processor.h
+++ linux-810/include/asm-x86_64/processor.h
@@ -162,6 +162,11 @@ static inline void clear_in_cr4 (unsigne
  */
 #define TASK_SIZE64	(0x800000000000UL - 4096)
 
+#define __HAVE_ARCH_ALIGN_STACK
+extern unsigned long arch_align_stack(unsigned long sp);
+
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
+
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/linux/mm.h linux-810/include/linux/mm.h
--- linux-804/include/linux/mm.h
+++ linux-810/include/linux/mm.h
@@ -840,7 +840,14 @@ extern struct vm_area_struct *copy_vma(s
 extern void exit_mmap(struct mm_struct *);
 extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
 
-extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+extern unsigned long get_unmapped_area_prot(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, int);
+
+
+static inline unsigned long get_unmapped_area(struct file * file, unsigned long addr, 
+		unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0);	
+}
 
 extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
 	unsigned long len, unsigned long prot,
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/linux/resource.h linux-810/include/linux/resource.h
--- linux-804/include/linux/resource.h
+++ linux-810/include/linux/resource.h
@@ -52,8 +52,11 @@ struct rlimit {
 /*
  * Limit the stack by to some sane default: root can always
  * increase this limit if needed..  8MB seems reasonable.
+ *
+ * (2MB more to cover randomization effects.)
  */
-#define _STK_LIM	(8*1024*1024)
+#define _STK_LIM	(10*1024*1024)
+#define EXEC_STACK_BIAS	(2*1024*1024)
 
 /*
  * GPG wants 32kB of mlocked memory, to make sure pass phrases
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/linux/sched.h linux-810/include/linux/sched.h
--- linux-804/include/linux/sched.h
+++ linux-810/include/linux/sched.h
@@ -36,6 +36,8 @@
 #include <linux/seccomp.h>
 
 struct exec_domain;
+extern int exec_shield;
+extern int print_fatal_signals;
 
 /*
  * cloning flags:
@@ -197,6 +199,10 @@ extern int sysctl_max_map_count;
 extern unsigned long
 arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
 		       unsigned long, unsigned long);
+
+extern unsigned long
+arch_get_unmapped_exec_area(struct file *, unsigned long, unsigned long,
+		       unsigned long, unsigned long);
 extern unsigned long
 arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
@@ -218,6 +224,9 @@ struct mm_struct {
 	unsigned long (*get_unmapped_area) (struct file *filp,
 				unsigned long addr, unsigned long len,
 				unsigned long pgoff, unsigned long flags);
+	unsigned long (*get_unmapped_exec_area) (struct file *filp,
+				unsigned long addr, unsigned long len,
+				unsigned long pgoff, unsigned long flags);
 	void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
         unsigned long mmap_base;		/* base of mmap area */
         unsigned long cached_hole_size;         /* if non-zero, the largest hole below free_area_cache */
diff -urNp --exclude-from=/home/davej/.exclude linux-804/include/linux/sysctl.h linux-810/include/linux/sysctl.h
--- linux-804/include/linux/sysctl.h
+++ linux-810/include/linux/sysctl.h
@@ -92,6 +92,9 @@ enum
 
 	KERN_CAP_BSET=14,	/* int: capability bounding set */
 	KERN_PANIC=15,		/* int: panic timeout */
+	KERN_EXEC_SHIELD=1000,	/* int: exec-shield enabled (0/1/2) */
+	KERN_PRINT_FATAL=1001,	/* int: print fatal signals (0/1/2) */
+	KERN_VDSO=1002,		/* int: VDSO enabled (0/1) */
 	KERN_REALROOTDEV=16,	/* real root device to mount after initrd */
 
 	KERN_SPARC_REBOOT=21,	/* reboot command on Sparc */
diff -urNp --exclude-from=/home/davej/.exclude linux-804/kernel/signal.c linux-810/kernel/signal.c
--- linux-804/kernel/signal.c
+++ linux-810/kernel/signal.c
@@ -1209,6 +1209,37 @@ kill_proc_info(int sig, struct siginfo *
 	return error;
 }
 
+int print_fatal_signals = 0;
+
+static void print_fatal_signal(struct pt_regs *regs, int signr)
+{
+	printk("%s/%d: potentially unexpected fatal signal %d.\n",
+		current->comm, current->pid, signr);
+		
+#ifdef __i386__
+	printk("code at %08lx: ", regs->eip);
+	{
+		int i;
+		for (i = 0; i < 16; i++) {
+			unsigned char insn;
+
+			__get_user(insn, (unsigned char *)(regs->eip + i));
+			printk("%02x ", insn);
+		}
+	}
+#endif	
+	printk("\n");
+	show_regs(regs);
+}
+
+static int __init setup_print_fatal_signals(char *str)
+{
+	get_option (&str, &print_fatal_signals);
+
+	return 1;
+}
+
+__setup("print-fatal-signals=", setup_print_fatal_signals);
 
 /*
  * kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1859,6 +1890,11 @@ relock:
 		if (!signr)
 			break; /* will return 0 */
 
+		if ((signr == SIGSEGV) && print_fatal_signals) {
+			spin_unlock_irq(&current->sighand->siglock);
+			print_fatal_signal(regs, signr);
+			spin_lock_irq(&current->sighand->siglock);
+		}
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
 			ptrace_signal_deliver(regs, cookie);
 
@@ -1954,6 +1990,8 @@ relock:
 		 * Anything else is fatal, maybe with a core dump.
 		 */
 		current->flags |= PF_SIGNALED;
+		if (print_fatal_signals)
+			print_fatal_signal(regs, signr);
 		if (sig_kernel_coredump(signr)) {
 			/*
 			 * If it was able to dump core, this kills all
diff -urNp --exclude-from=/home/davej/.exclude linux-804/kernel/sysctl.c linux-810/kernel/sysctl.c
--- linux-804/kernel/sysctl.c
+++ linux-810/kernel/sysctl.c
@@ -74,6 +74,19 @@ extern int proc_unknown_nmi_panic(ctl_ta
 				  void __user *, size_t *, loff_t *);
 #endif
 
+extern unsigned int vdso_enabled;
+
+int exec_shield = 1;
+
+static int __init setup_exec_shield(char *str)
+{
+        get_option (&str, &exec_shield);
+
+        return 1;
+}
+
+__setup("exec-shield=", setup_exec_shield);
+
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
@@ -279,6 +292,32 @@ static ctl_table kern_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 	{
+		.ctl_name	= KERN_EXEC_SHIELD,
+		.procname	= "exec-shield",
+		.data		= &exec_shield,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= KERN_PRINT_FATAL,
+		.procname	= "print-fatal-signals",
+		.data		= &print_fatal_signals,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#ifdef __i386__
+	{
+		.ctl_name	= KERN_VDSO,
+		.procname	= "vdso",
+		.data		= &vdso_enabled,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#endif
+	{
 		.ctl_name	= KERN_CORE_USES_PID,
 		.procname	= "core_uses_pid",
 		.data		= &core_uses_pid,
--- linux-2.6.13/mm/fremap.c~	2005-10-13 17:34:08.000000000 -0400
+++ linux-2.6.13/mm/fremap.c	2005-10-13 17:34:58.000000000 -0400
@@ -83,13 +83,15 @@ int install_page(struct mm_struct *mm, s
 	 * caller about it.
 	 */
 	err = -EINVAL;
-	inode = vma->vm_file->f_mapping->host;
-	size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	if (!page->mapping || page->index >= size)
-		goto unlock;
-	err = -ENOMEM;
-	if (page_mapcount(page) > INT_MAX/2)
-		goto unlock;
+	if (vma->vm_file) {
+		inode = vma->vm_file->f_mapping->host;
+		size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+		if (!page->mapping || page->index >= size)
+			goto unlock;
+		err = -ENOMEM;
+		if (page_mapcount(page) > INT_MAX/2)
+			goto unlock;
+	}
 
 	if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
 		inc_mm_counter(mm, file_rss);
diff -urNp --exclude-from=/home/davej/.exclude linux-804/mm/mmap.c linux-810/mm/mmap.c
--- linux-804/mm/mmap.c
+++ linux-810/mm/mmap.c
@@ -24,6 +24,7 @@
 #include <linux/mount.h>
 #include <linux/mempolicy.h>
 #include <linux/rmap.h>
+#include <linux/random.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -342,6 +343,8 @@ static inline void
 __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
 		struct vm_area_struct *prev, struct rb_node *rb_parent)
 {
+	if (vma->vm_flags & VM_EXEC)
+		arch_add_exec_range(mm, vma->vm_end);
 	if (prev) {
 		vma->vm_next = prev->vm_next;
 		prev->vm_next = vma;
@@ -446,6 +449,8 @@ __vma_unlink(struct mm_struct *mm, struc
 	rb_erase(&vma->vm_rb, &mm->mm_rb);
 	if (mm->mmap_cache == vma)
 		mm->mmap_cache = prev;
+	if (vma->vm_flags & VM_EXEC)
+		arch_remove_exec_range(mm, vma->vm_end);
 }
 
 /*
@@ -751,6 +756,8 @@ struct vm_area_struct *vma_merge(struct 
 		} else					/* cases 2, 5, 7 */
 			vma_adjust(prev, prev->vm_start,
 				end, prev->vm_pgoff, NULL);
+		if (prev->vm_flags & VM_EXEC)
+			arch_add_exec_range(mm, prev->vm_end);
 		return prev;
 	}
 
@@ -922,7 +929,7 @@ unsigned long do_mmap_pgoff(struct file 
 	/* Obtain the address to map to. we verify (or select) it and ensure
 	 * that it represents a valid section of the address space.
 	 */
-	addr = get_unmapped_area(file, addr, len, pgoff, flags);
+	addr = get_unmapped_area_prot(file, addr, len, pgoff, flags, prot & PROT_EXEC);
 	if (addr & ~PAGE_MASK)
 		return addr;
 
@@ -1328,16 +1335,21 @@ void arch_unmap_area_topdown(struct mm_s
 		mm->free_area_cache = mm->mmap_base;
 }
 
+
 unsigned long
-get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
-		unsigned long pgoff, unsigned long flags)
+get_unmapped_area_prot(struct file *file, unsigned long addr, unsigned long len,
+		unsigned long pgoff, unsigned long flags, int exec)
 {
 	unsigned long ret;
 
 	if (!(flags & MAP_FIXED)) {
 		unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
 
-		get_area = current->mm->get_unmapped_area;
+		if (exec && current->mm->get_unmapped_exec_area)
+			get_area = current->mm->get_unmapped_exec_area;
+		else
+			get_area = current->mm->get_unmapped_area;
+
 		if (file && file->f_op && file->f_op->get_unmapped_area)
 			get_area = file->f_op->get_unmapped_area;
 		addr = get_area(file, addr, len, pgoff, flags);
@@ -1368,7 +1380,71 @@ get_unmapped_area(struct file *file, uns
 	return addr;
 }
 
-EXPORT_SYMBOL(get_unmapped_area);
+EXPORT_SYMBOL(get_unmapped_area_prot);
+
+#define SHLIB_BASE             0x00111000
+
+unsigned long arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
+		unsigned long len0, unsigned long pgoff, unsigned long flags)
+{
+	unsigned long addr = addr0, len = len0;
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	unsigned long tmp;
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	if (!addr && !(flags & MAP_FIXED))
+		addr = randomize_range(SHLIB_BASE, 0x01000000, len);
+
+	if (addr) {
+		addr = PAGE_ALIGN(addr);
+		vma = find_vma(mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start)) {
+			return addr;
+		}
+	}
+
+	addr = SHLIB_BASE;
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+
+		if (!vma || addr + len <= vma->vm_start) {
+			/*
+			 * Must not let a PROT_EXEC mapping get into the
+			 * brk area:
+			 */
+			if (addr + len > mm->brk)
+				goto failed;
+
+			/*
+			 * Up until the brk area we randomize addresses
+			 * as much as possible:
+			 */
+			if (addr >= 0x01000000) {
+				tmp = randomize_range(0x01000000, PAGE_ALIGN(max(mm->start_brk, (unsigned long)0x08000000)), len);
+				vma = find_vma(mm, tmp);
+				if (TASK_SIZE - len >= tmp &&
+				    (!vma || tmp + len <= vma->vm_start))
+					return tmp;
+			}
+			/*
+			 * Ok, randomization didnt work out - return
+			 * the result of the linear search:
+			 */
+			return addr;
+		}
+		addr = vma->vm_end;
+	}
+
+failed:
+	return current->mm->get_unmapped_area(filp, addr0, len0, pgoff, flags);
+}
+
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
 struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
@@ -1443,6 +1519,14 @@ out:
 	return prev ? prev->vm_next : vma;
 }
 
+static int over_stack_limit(unsigned long sz)
+{
+	if (sz < EXEC_STACK_BIAS)
+		return 0;
+	return (sz - EXEC_STACK_BIAS) >
+			current->signal->rlim[RLIMIT_STACK].rlim_cur;
+}
+
 /*
  * Verify that the stack growth is acceptable and
  * update accounting. This is shared with both the
@@ -1458,7 +1542,7 @@ static int acct_stack_growth(struct vm_a
 		return -ENOMEM;
 
 	/* Stack limit test */
-	if (size > rlim[RLIMIT_STACK].rlim_cur)
+	if (over_stack_limit(size))
 		return -ENOMEM;
 
 	/* mlock limit tests */
@@ -1740,10 +1824,14 @@ int split_vma(struct mm_struct * mm, str
 	if (new->vm_ops && new->vm_ops->open)
 		new->vm_ops->open(new);
 
-	if (new_below)
+	if (new_below) {
+		unsigned long old_end = vma->vm_end;
+
 		vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
 			((addr - new->vm_start) >> PAGE_SHIFT), new);
-	else
+		if (vma->vm_flags & VM_EXEC)
+			arch_remove_exec_range(mm, old_end);
+	} else
 		vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
 
 	return 0;
@@ -2048,6 +2048,7 @@ void exit_mmap(struct mm_struct *mm)
 	vm_unacct_memory(nr_accounted);
 	free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
 	tlb_finish_mmu(tlb, 0, end);
+	arch_flush_exec_range(mm);
 
 	/*
 	 * Walk the list again, actually closing and freeing it,
diff -urNp --exclude-from=/home/davej/.exclude linux-804/mm/mprotect.c linux-810/mm/mprotect.c
--- linux-804/mm/mprotect.c
+++ linux-810/mm/mprotect.c
@@ -22,6 +22,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
@@ -106,7 +107,7 @@ mprotect_fixup(struct vm_area_struct *vm
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long oldflags = vma->vm_flags;
 	long nrpages = (end - start) >> PAGE_SHIFT;
-	unsigned long charged = 0;
+	unsigned long charged = 0, old_end = vma->vm_end;
 	pgprot_t newprot;
 	pgoff_t pgoff;
 	int error;
@@ -167,6 +168,8 @@ success:
 	 */
 	vma->vm_flags = newflags;
 	vma->vm_page_prot = newprot;
+	if (oldflags & VM_EXEC)
+		arch_remove_exec_range(current->mm, old_end);
 	change_protection(vma, start, end, newprot);
 	__vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
 	__vm_stat_account(mm, newflags, vma->vm_file, nrpages);
diff -urNp --exclude-from=/home/davej/.exclude linux-804/mm/mremap.c linux-810/mm/mremap.c
--- linux-804/mm/mremap.c
+++ linux-810/mm/mremap.c
@@ -407,8 +407,8 @@ unsigned long do_mremap(unsigned long ad
 			if (vma->vm_flags & VM_MAYSHARE)
 				map_flags |= MAP_SHARED;
 
-			new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
-						vma->vm_pgoff, map_flags);
+			new_addr = get_unmapped_area_prot(vma->vm_file, 0, new_len, 
+				vma->vm_pgoff, map_flags, vma->vm_flags & VM_EXEC);
 			ret = new_addr;
 			if (new_addr & ~PAGE_MASK)
 				goto out;
diff -urNp --exclude-from=/home/davej/.exclude linux-812/arch/i386/kernel/cpu/common.c linux-813/arch/i386/kernel/cpu/common.c
--- linux-812/arch/i386/kernel/cpu/common.c
+++ linux-813/arch/i386/kernel/cpu/common.c
@@ -397,6 +397,13 @@ void __devinit identify_cpu(struct cpuin
 	if (disable_pse)
 		clear_bit(X86_FEATURE_PSE, c->x86_capability);
 
+	if (exec_shield != 0) {
+#ifdef CONFIG_HIGHMEM64G   /* NX implies PAE */
+		if (!test_bit(X86_FEATURE_NX, c->x86_capability))
+#endif
+		clear_bit(X86_FEATURE_SEP, c->x86_capability);
+	}
+
 	/* If the model name is still unset, do table lookup. */
 	if ( !c->x86_model_id[0] ) {
 		char *p;
diff -urpN --exclude-from=/home/devel/davej/.exclude linux-2.6.13/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.13-a/arch/x86_64/ia32/ia32_binfmt.c
--- linux-2.6.13/arch/x86_64/ia32/ia32_binfmt.c	2005-10-14 20:55:36.000000000 -0400
+++ linux-2.6.13-a/arch/x86_64/ia32/ia32_binfmt.c	2005-10-14 20:56:15.000000000 -0400
@@ -249,8 +249,6 @@ elf_core_copy_task_xfpregs(struct task_s
 #define elf_check_arch(x) \
 	((x)->e_machine == EM_386)
 
-extern int force_personality32;
-
 #define ELF_EXEC_PAGESIZE PAGE_SIZE
 #define ELF_HWCAP (boot_cpu_data.x86_capability[0])
 #define ELF_PLATFORM  ("i686")
@@ -264,8 +262,6 @@ do {							\
 		set_thread_flag(TIF_ABI_PENDING);		\
 	else							\
 		clear_thread_flag(TIF_ABI_PENDING);		\
-	/* XXX This overwrites the user set personality */	\
-	current->personality |= force_personality32;		\
 } while (0)
 
 /* Override some function names */
diff -urpN --exclude-from=/home/devel/davej/.exclude linux-2.6.13/arch/x86_64/kernel/process.c linux-2.6.13-a/arch/x86_64/kernel/process.c
--- linux-2.6.13/arch/x86_64/kernel/process.c	2005-10-14 20:55:36.000000000 -0400
+++ linux-2.6.13-a/arch/x86_64/kernel/process.c	2005-10-14 20:56:15.000000000 -0400
@@ -638,12 +638,6 @@ void set_personality_64bit(void)
 
 	/* Make sure to be in 64bit mode */
 	clear_thread_flag(TIF_IA32); 
-
-	/* TBD: overwrites user setup. Should have two bits.
-	   But 64bit processes have always behaved this way,
-	   so it's not too bad. The main problem is just that
-   	   32bit childs are affected again. */
-	current->personality &= ~READ_IMPLIES_EXEC;
 }
 
 asmlinkage long sys_fork(struct pt_regs *regs)
diff -urpN --exclude-from=/home/devel/davej/.exclude linux-2.6.13/arch/x86_64/kernel/setup64.c linux-2.6.13-a/arch/x86_64/kernel/setup64.c
--- linux-2.6.13/arch/x86_64/kernel/setup64.c	2005-10-14 20:55:36.000000000 -0400
+++ linux-2.6.13-a/arch/x86_64/kernel/setup64.c	2005-10-14 20:56:15.000000000 -0400
@@ -45,7 +45,7 @@ Control non executable mappings for 64bi
 on	Enable(default)
 off	Disable
 */ 
-int __init nonx_setup(char *str)
+void __init nonx_setup(const char *str)
 {
 	if (!strncmp(str, "on", 2)) {
                 __supported_pte_mask |= _PAGE_NX; 
@@ -53,29 +53,8 @@ int __init nonx_setup(char *str)
 	} else if (!strncmp(str, "off", 3)) {
 		do_not_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
-        }
-	return 0;
+        } 
 } 
-__setup("noexec=", nonx_setup);	/* parsed early actually */
-
-int force_personality32 = READ_IMPLIES_EXEC;
-
-/* noexec32=on|off
-Control non executable heap for 32bit processes.
-To control the stack too use noexec=off
-
-on	PROT_READ does not imply PROT_EXEC for 32bit processes
-off	PROT_READ implies PROT_EXEC (default)
-*/
-static int __init nonx32_setup(char *str)
-{
-	if (!strcmp(str, "on"))
-		force_personality32 &= ~READ_IMPLIES_EXEC;
-	else if (!strcmp(str, "off"))
-		force_personality32 |= READ_IMPLIES_EXEC;
-	return 0;
-}
-__setup("noexec32=", nonx32_setup);
 
 /*
  * Great future plan:
diff -urpN --exclude-from=/home/devel/davej/.exclude linux-2.6.13/include/asm-x86_64/pgtable.h linux-2.6.13-a/include/asm-x86_64/pgtable.h
--- linux-2.6.13/include/asm-x86_64/pgtable.h	2005-10-14 20:55:36.000000000 -0400
+++ linux-2.6.13-a/include/asm-x86_64/pgtable.h	2005-10-14 20:56:15.000000000 -0400
@@ -20,7 +20,7 @@ extern unsigned long __supported_pte_mas
 
 #define swapper_pg_dir init_level4_pgt
 
-extern int nonx_setup(char *str);
+extern void nonx_setup(const char *str);
 extern void paging_init(void);
 extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
 

linux-2.6-firmware-loader-timeout.patch:
 firmware_class.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-firmware-loader-timeout.patch ---

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=174589

The ipw driver sometimes takes a long time to load its firmware.
Whilst the ipw driver should be using the async interface of
the firmware loader to make this a non-issue, this is a minimal fix.

Signed-off-by: Dave Jones <davej at redhat.com>

--- linux-2.6.14/drivers/base/firmware_class.c~	2005-12-01 16:56:29.000000000 -0500
+++ linux-2.6.14/drivers/base/firmware_class.c	2005-12-01 16:56:35.000000000 -0500
@@ -31,7 +31,7 @@ enum {
 	FW_STATUS_READY_NOHOTPLUG,
 };
 
-static int loading_timeout = 10;	/* In seconds */
+static int loading_timeout = 60;	/* In seconds */
 
 /* fw_lock could be moved to 'struct firmware_priv' but since it is just
  * guarding for corner cases a global lock should be OK */

linux-2.6-ide-tune-locking.patch:
 piix.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-ide-tune-locking.patch ---
--- linux-2.6.12/drivers/ide/pci/piix.c~	2005-07-11 10:23:24.637181320 +0100
+++ linux-2.6.12/drivers/ide/pci/piix.c	2005-07-11 10:23:24.637181320 +0100
@@ -203,6 +203,8 @@
 	}
 }
 
+static spinlock_t tune_lock = SPIN_LOCK_UNLOCKED;
+
 /**
  *	piix_tune_drive		-	tune a drive attached to a PIIX
  *	@drive: drive to tune
@@ -229,7 +231,12 @@
 			    { 2, 3 }, };
 
 	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
-	spin_lock_irqsave(&ide_lock, flags);
+	
+	/* Master v slave is synchronized above us but the slave register is
+	   shared by the two hwifs so the corner case of two slave timeouts in
+	   parallel must be locked */
+	   
+	spin_lock_irqsave(&tune_lock, flags);
 	pci_read_config_word(dev, master_port, &master_data);
 	if (is_slave) {
 		master_data = master_data | 0x4000;
@@ -249,7 +256,7 @@
 	pci_write_config_word(dev, master_port, master_data);
 	if (is_slave)
 		pci_write_config_byte(dev, slave_port, slave_data);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&tune_lock, flags);
 }
 
 /**

linux-2.6-input-kill-stupid-messages.patch:
 atkbd.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-input-kill-stupid-messages.patch ---
--- linux-2.6.11/drivers/input/keyboard/atkbd.c~	2005-04-30 15:40:09.000000000 -0400
+++ linux-2.6.11/drivers/input/keyboard/atkbd.c	2005-04-30 15:40:35.000000000 -0400
@@ -328,7 +328,7 @@ static irqreturn_t atkbd_interrupt(struc
 			atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
 			goto out;
 		case ATKBD_RET_ERR:
-			printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+//			printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
 			goto out;
 	}
 
@@ -348,9 +348,13 @@
 			break;
 		case ATKBD_KEY_UNKNOWN:
 			if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
+#if 0
+/* Quite a few key switchers and other tools trigger this and it confuses
+   people who can do nothing about it */			
 				printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
 				       "like XFree86, might be trying access hardware directly.\n",
 				       data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+#endif				       
 			} else {
 				printk(KERN_WARNING "atkbd.c: Unknown key %s "
 				       "(%s set %d, code %#x on %s).\n",


linux-2.6-input-usblegacy.patch:
 i8042.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-input-usblegacy.patch ---
Some laptops seem to lose their touchpads.
This patch is currently an experiment to see if its
usb legacy that's causing the problem.

--- linux-2.6.12/drivers/input/serio/i8042.c~	2005-08-28 17:17:55.000000000 -0400
+++ linux-2.6.12/drivers/input/serio/i8042.c	2005-08-28 17:19:42.000000000 -0400
@@ -576,8 +576,10 @@ static int __init i8042_check_mux(void)
 
 	/* Workaround for interference with USB Legacy emulation */
 	/* that causes a v10.12 MUX to be found. */
-	if (mux_version == 0xAC)
+	if (mux_version == 0xAC) {
+		printk(KERN_INFO "i8042.c: MUX probe failed. USB legacy enabled in BIOS?\n");
 		return -1;
+	}
 
 	printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
 		(mux_version >> 4) & 0xf, mux_version & 0xf);

linux-2.6-kdump-needs-not-embedded.patch:
 Kconfig |    3 +--
 1 files changed, 1 insertion(+), 2 deletions(-)

--- NEW FILE linux-2.6-kdump-needs-not-embedded.patch ---
--- linux-2.6.13/arch/i386/Kconfig.orig	2005-08-31 17:24:28.546898366 -0400
+++ linux-2.6.13/arch/i386/Kconfig	2005-08-31 17:26:59.145863734 -0400
@@ -944,7 +944,7 @@ config SECCOMP
 source kernel/Kconfig.hz
 
 config PHYSICAL_START
-	hex "Physical address where the kernel is loaded" if EMBEDDED
+	hex "Physical address where the kernel is loaded"
 	default "0x100000"
 	help
 	  This gives the physical address where the kernel is loaded.
@@ -973,7 +973,6 @@ config KEXEC
 
 config CRASH_DUMP
 	bool "kernel crash dumps (EXPERIMENTAL)"
-	depends on EMBEDDED
 	depends on EXPERIMENTAL
 	depends on HIGHMEM
 	help

linux-2.6-max-symlinks.patch:
 namei.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-max-symlinks.patch ---
Bump up the maximum nested amount of symlinks.

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/include/linux/namei.h linux-10000/include/linux/namei.h
--- linux-3022/include/linux/namei.h
+++ linux-10000/include/linux/namei.h
@@ -10,7 +10,7 @@ struct open_intent {
 	int	create_mode;
 };
 
-enum { MAX_NESTED_LINKS = 5 };
+enum { MAX_NESTED_LINKS = 8 };
 
 struct nameidata {
 	struct dentry	*dentry;

linux-2.6-missing-exports.patch:
 drivers/char/random.c |    1 +
 lib/kobject_uevent.c  |    1 +
 2 files changed, 2 insertions(+)

--- NEW FILE linux-2.6-missing-exports.patch ---
WARNING:
/usr/src/build/566509-ppc64iseries/install/lib/modules/2.6.11-1.1311_FC4/kernel/drivers/input/input.ko
needs unknown symbol add_input_randomness

--- linux-2.6.11/drivers/char/random.c~	2005-05-14 16:42:24.000000000 -0400
+++ linux-2.6.11/drivers/char/random.c	2005-05-14 16:42:46.000000000 -0400
@@ -646,6 +646,7 @@ extern void add_input_randomness(unsigne
 	add_timer_randomness(&input_timer_state,
 			     (type << 4) ^ code ^ (code >> 4) ^ value);
 }
+EXPORT_SYMBOL_GPL(add_input_randomness);
 
 void add_interrupt_randomness(int irq)
 {


WARNING:
/usr/src/build/566509-ppc64iseries/install/lib/modules/2.6.11-1.1311_FC4/kernel/drivers/input/input.ko
needs unknown symbol hotplug_path

--- linux-2.6.11/lib/kobject_uevent.c~	2005-05-14 16:45:13.000000000 -0400
+++ linux-2.6.11/lib/kobject_uevent.c	2005-05-14 16:45:27.000000000 -0400
@@ -178,6 +178,7 @@ static inline int send_uevent(const char
 
 #ifdef CONFIG_HOTPLUG
 char hotplug_path[HOTPLUG_PATH_LEN] = "/sbin/hotplug";
+EXPORT_SYMBOL_GPL(hotplug_path);
 u64 hotplug_seqnum;
 static DEFINE_SPINLOCK(sequence_lock);
 

linux-2.6-modsign-core.patch:
 linux-2.6.12/kernel/module-verify.c  |    2 
 linux-900/include/linux/module.h     |    3 
 linux-900/init/Kconfig               |   16 +
 linux-900/kernel/Makefile            |    3 
 linux-900/kernel/module-verify-sig.c |  442 +++++++++++++++++++++++++++++++++++
 linux-900/kernel/module-verify.c     |  340 ++++++++++++++++++++++++++
 linux-900/kernel/module-verify.h     |   37 ++
 linux-900/kernel/module.c            |   19 +
 8 files changed, 857 insertions(+), 5 deletions(-)

--- NEW FILE linux-2.6-modsign-core.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-811/include/linux/module.h linux-900/include/linux/module.h
--- linux-811/include/linux/module.h
+++ linux-900/include/linux/module.h
@@ -277,6 +277,9 @@ struct module
 
 	/* Am I GPL-compatible */
 	int license_gplok;
+	
+	/* Am I gpg signed */
+	int gpgsig_ok;
 
 #ifdef CONFIG_MODULE_UNLOAD
 	/* Reference counts */
diff -urNp --exclude-from=/home/davej/.exclude linux-811/init/Kconfig linux-900/init/Kconfig
--- linux-811/init/Kconfig
+++ linux-900/init/Kconfig
@@ -434,6 +434,22 @@ config MODULE_SRCVERSION_ALL
 	  the version).  With this option, such a "srcversion" field
 	  will be created for all modules.  If unsure, say N.
 
+config MODULE_SIG
+	bool "Module signature verification (EXPERIMENTAL)"
+	depends on MODULES && EXPERIMENTAL
+	select CRYPTO
+	select CRYPTO_SHA1
+	select CRYPTO_SIGNATURE
+	help
+	  Check modules for valid signatures upon load.
+
+config MODULE_SIG_FORCE
+	bool "Required modules to be validly signed (EXPERIMENTAL)"
+	depends on MODULE_SIG
+	help
+	  Reject unsigned modules or signed modules for which we don't have a
+	  key.
+
 config KMOD
 	bool "Automatic kernel module loading"
 	depends on MODULES
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/Makefile linux-900/kernel/Makefile
--- linux-811/kernel/Makefile
+++ linux-900/kernel/Makefile
@@ -13,7 +13,8 @@ obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o spinlock.o
 obj-$(CONFIG_UID16) += uid16.o
-obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_MODULES) += module.o module-verify.o
+obj-$(CONFIG_MODULE_SIG) += module-verify-sig.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_PM) += power/
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module.c linux-900/kernel/module.c
--- linux-811/kernel/module.c
+++ linux-900/kernel/module.c
@@ -38,6 +38,7 @@
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
+#include "module-verify.h"
 
 #if 0
 #define DEBUGP printk
@@ -1413,6 +1414,7 @@ static struct module *load_module(void _
 	long err = 0;
 	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
 	struct exception_table_entry *extable;
	mm_segment_t old_fs;
+	int gpgsig_ok;
 
 	DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -1438,8 +1440,13 @@ static struct module *load_module(void _
 		goto free_hdr;
 	}
 
-	if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr))
-		goto truncated;
+	/* verify the module (validates ELF and checks signature) */
+	gpgsig_ok = 0;
+	err = module_verify(hdr, len);
+	if (err < 0)
+		goto free_hdr;
+	if (err == 1)
+		gpgsig_ok = 1;
 
 	/* Convenience variables */
 	sechdrs = (void *)hdr + hdr->e_shoff;
@@ -1476,6 +1483,7 @@ static struct module *load_module(void _
 		goto free_hdr;
 	}
 	mod = (void *)sechdrs[modindex].sh_addr;
+	mod->gpgsig_ok = gpgsig_ok;
 
 	if (symindex == 0) {
 		printk(KERN_WARNING "%s: module has no symbols (stripped?)\n",
@@ -2078,8 +2086,13 @@ void print_modules(void)
 	struct module *mod;
 
 	printk("Modules linked in:");
-	list_for_each_entry(mod, &modules, list)
+	list_for_each_entry(mod, &modules, list) {
 		printk(" %s", mod->name);
+#if CONFIG_MODULE_SIG		
+		if (!mod->gpgsig_ok)
+			printk("(U)");
+#endif		
+	}
 	printk("\n");
 }
 
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify.c linux-900/kernel/module-verify.c
--- linux-811/kernel/module-verify.c
+++ linux-900/kernel/module-verify.c
@@ -0,0 +1,340 @@
+/* module-verify.c: module verifier
+ *
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/elf.h>
+#include <linux/crypto.h>
+#include <linux/crypto/ksign.h>
+#include "module-verify.h"
+
+#if 0
+#define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__)
+#else
+#define _debug(FMT, ...) do {} while (0)
+#endif
+
+static int module_verify_elf(struct module_verify_data *mvdata);
+
+/*****************************************************************************/
+/*
+ * verify a module's integrity
+ * - check the ELF is viable
+ * - check the module's signature if it has one
+ */
+int module_verify(const Elf_Ehdr *hdr, size_t size)
+{
+	struct module_verify_data mvdata;
+	int ret;
+
+	memset(&mvdata, 0, sizeof(mvdata));
+	mvdata.buffer	= hdr;
+	mvdata.hdr	= hdr;
+	mvdata.size	= size;
+
+	ret = module_verify_elf(&mvdata);
+	if (ret < 0) {
+		if (ret == -ELIBBAD)
+			printk("Module failed ELF checks\n");
+		goto error;
+	}
+
+#ifdef CONFIG_MODULE_SIG
+	ret = module_verify_signature(&mvdata);
+#endif
+
+ error:
+	kfree(mvdata.secsizes);
+	kfree(mvdata.canonlist);
+	return ret;
+
+} /* end module_verify() */
+
+/*****************************************************************************/
+/*
+ * verify the ELF structure of a module
+ */
+static int module_verify_elf(struct module_verify_data *mvdata)
+{
+	const Elf_Ehdr *hdr = mvdata->hdr;
+	const Elf_Shdr *section, *section2, *secstop;
+	const Elf_Rela *relas, *rela, *relastop;
+	const Elf_Rel *rels, *rel, *relstop;
+	const Elf_Sym *symbol, *symstop;
+	size_t size, sssize, *secsize, tmp, tmp2;
+	long last;
+	int line;
+
+	size = mvdata->size;
+	mvdata->nsects = hdr->e_shnum;
+
+#define elfcheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto elfcheck_error; } } while(0)
+
+#define seccheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto seccheck_error; } } while(0)
+
+#define symcheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto symcheck_error; } } while(0)
+
+#define relcheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto relcheck_error; } } while(0)
+
+#define relacheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto relacheck_error; } } while(0)
+
+	/* validate the ELF header */
+	elfcheck(hdr->e_ehsize < size);
+	elfcheck(hdr->e_entry == 0);
+	elfcheck(hdr->e_phoff == 0);
+	elfcheck(hdr->e_phnum == 0);
+
+	elfcheck(hdr->e_shnum < SHN_LORESERVE);
+	elfcheck(hdr->e_shoff < size);
+	elfcheck(hdr->e_shoff >= hdr->e_ehsize);
+	elfcheck((hdr->e_shoff & (sizeof(long) - 1)) == 0);
+	elfcheck(hdr->e_shstrndx > 0);
+	elfcheck(hdr->e_shstrndx < hdr->e_shnum);
+	elfcheck(hdr->e_shentsize == sizeof(Elf_Shdr));
+
+	tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
+	elfcheck(tmp < size - hdr->e_shoff);
+
+	/* allocate a table to hold in-file section sizes */
+	mvdata->secsizes = kmalloc(hdr->e_shnum * sizeof(size_t), GFP_KERNEL);
+	if (!mvdata->secsizes)
+		return -ENOMEM;
+
+	memset(mvdata->secsizes, 0, hdr->e_shnum * sizeof(size_t));
+
+	/* validate the ELF section headers */
+	mvdata->sections = mvdata->buffer + hdr->e_shoff;
+	secstop = mvdata->sections + mvdata->nsects;
+
+	sssize = mvdata->sections[hdr->e_shstrndx].sh_size;
+	elfcheck(sssize > 0);
+
+	section = mvdata->sections;
+	seccheck(section->sh_type == SHT_NULL);
+	seccheck(section->sh_size == 0);
+	seccheck(section->sh_offset == 0);
+
+	secsize = mvdata->secsizes + 1;
+	for (section++; section < secstop; secsize++, section++) {
+		seccheck(section->sh_name < sssize);
+		seccheck(section->sh_link < hdr->e_shnum);
+
+		if (section->sh_entsize > 0)
+			seccheck(section->sh_size % section->sh_entsize == 0);
+
+		seccheck(section->sh_offset >= hdr->e_ehsize);
+		seccheck(section->sh_offset < size);
+
+		/* determine the section's in-file size */
+		tmp = size - section->sh_offset;
+		if (section->sh_offset < hdr->e_shoff)
+			tmp = hdr->e_shoff - section->sh_offset;
+
+		for (section2 = mvdata->sections + 1; section2 < secstop; section2++) {
+			if (section->sh_offset < section2->sh_offset) {
+				tmp2 = section2->sh_offset - section->sh_offset;
+				if (tmp2 < tmp)
+					tmp = tmp2;
+			}
+		}
+		*secsize = tmp;
+
+		_debug("Section %ld: %zx bytes at %lx\n",
+		       section - mvdata->sections,
+		       *secsize,
+		       section->sh_offset);
+
+		/* perform section type specific checks */
+		switch (section->sh_type) {
+		case SHT_NOBITS:
+			break;
+
+		case SHT_REL:
+			seccheck(section->sh_entsize == sizeof(Elf_Rel));
+			goto more_rel_checks;
+
+		case SHT_RELA:
+			seccheck(section->sh_entsize == sizeof(Elf_Rela));
+		more_rel_checks:
+			seccheck(section->sh_info > 0);
+			seccheck(section->sh_info < hdr->e_shnum);
+			goto more_sec_checks;
+
+		case SHT_SYMTAB:
+			seccheck(section->sh_entsize == sizeof(Elf_Sym));
+			goto more_sec_checks;
+
+		default:
+		more_sec_checks:
+			/* most types of section must be contained entirely
+			 * within the file */
+			seccheck(section->sh_size <= *secsize);
+			break;
+		}
+	}
+
+	/* validate the ELF section names */
+	section = &mvdata->sections[hdr->e_shstrndx];
+
+	seccheck(section->sh_offset != hdr->e_shoff);
+
+	mvdata->secstrings = mvdata->buffer + section->sh_offset;
+
+	last = -1;
+	for (section = mvdata->sections + 1; section < secstop; section++) {
+		const char *secname;
+		tmp = sssize - section->sh_name;
+		secname = mvdata->secstrings + section->sh_name;
+		seccheck(secname[0] != 0);
+		if (section->sh_name > last)
+			last = section->sh_name;
+	}
+
+	if (last > -1) {
+		tmp = sssize - last;
+		elfcheck(memchr(mvdata->secstrings + last, 0, tmp) != NULL);
+	}
+
+	/* look for various sections in the module */
+	for (section = mvdata->sections + 1; section < secstop; section++) {
+		switch (section->sh_type) {
+		case SHT_SYMTAB:
+			if (strcmp(mvdata->secstrings + section->sh_name,
+				   ".symtab") == 0
+			    ) {
+				seccheck(mvdata->symbols == NULL);
+				mvdata->symbols =
+					mvdata->buffer + section->sh_offset;
+				mvdata->nsyms =
+					section->sh_size / sizeof(Elf_Sym);
+				seccheck(section->sh_size > 0);
+			}
+			break;
+
+		case SHT_STRTAB:
+			if (strcmp(mvdata->secstrings + section->sh_name,
+				   ".strtab") == 0
+			    ) {
+				seccheck(mvdata->strings == NULL);
+				mvdata->strings =
+					mvdata->buffer + section->sh_offset;
+				sssize = mvdata->nstrings = section->sh_size;
+				seccheck(section->sh_size > 0);
+			}
+			break;
+		}
+	}
+
+	if (!mvdata->symbols) {
+		printk("Couldn't locate module symbol table\n");
+		goto format_error;
+	}
+
+	if (!mvdata->strings) {
+		printk("Couldn't locate module strings table\n");
+		goto format_error;
+	}
+
+	/* validate the symbol table */
+	symstop = mvdata->symbols + mvdata->nsyms;
+
+	symbol = mvdata->symbols;
+	symcheck(ELF_ST_TYPE(symbol[0].st_info) == STT_NOTYPE);
+	symcheck(symbol[0].st_shndx == SHN_UNDEF);
+	symcheck(symbol[0].st_value == 0);
+	symcheck(symbol[0].st_size == 0);
+
+	last = -1;
+	for (symbol++; symbol < symstop; symbol++) {
+		symcheck(symbol->st_name < sssize);
+		if (symbol->st_name > last)
+			last = symbol->st_name;
+		symcheck(symbol->st_shndx < mvdata->nsects ||
+			 symbol->st_shndx >= SHN_LORESERVE);
+	}
+
+	if (last > -1) {
+		tmp = sssize - last;
+		elfcheck(memchr(mvdata->strings + last, 0, tmp) != NULL);
+	}
+
+	/* validate each relocation table as best we can */
+	for (section = mvdata->sections + 1; section < secstop; section++) {
+		section2 = mvdata->sections + section->sh_info;
+
+		switch (section->sh_type) {
+		case SHT_REL:
+			rels = mvdata->buffer + section->sh_offset;
+			relstop = mvdata->buffer + section->sh_offset + section->sh_size;
+
+			for (rel = rels; rel < relstop; rel++) {
+				relcheck(rel->r_offset < section2->sh_size);
+				relcheck(ELF_R_SYM(rel->r_info) < mvdata->nsyms);
+			}
+
+			break;
+
+		case SHT_RELA:
+			relas = mvdata->buffer + section->sh_offset;
+			relastop = mvdata->buffer + section->sh_offset + section->sh_size;
+
+			for (rela = relas; rela < relastop; rela++) {
+				relacheck(rela->r_offset < section2->sh_size);
+				relacheck(ELF_R_SYM(rela->r_info) < mvdata->nsyms);
+			}
+
+			break;
+
+		default:
+			break;
+		}
+	}
+
+
+	_debug("ELF okay\n");
+	return 0;
+
+ elfcheck_error:
+	printk("Verify ELF error (assertion %d)\n", line);
+	goto format_error;
+
+ seccheck_error:
+	printk("Verify ELF error [sec %ld] (assertion %d)\n",
+	       (long)(section - mvdata->sections), line);
+	goto format_error;
+
+ symcheck_error:
+	printk("Verify ELF error [sym %ld] (assertion %d)\n",
+	       (long)(symbol - mvdata->symbols), line);
+	goto format_error;
+
+ relcheck_error:
+	printk("Verify ELF error [sec %ld rel %ld] (assertion %d)\n",
+	       (long)(section - mvdata->sections),
+	       (long)(rel - rels), line);
+	goto format_error;
+
+ relacheck_error:
+	printk("Verify ELF error [sec %ld rela %ld] (assertion %d)\n",
+	       (long)(section - mvdata->sections),
+	       (long)(rela - relas), line);
+	goto format_error;
+
+ format_error:
+	return -ELIBBAD;
+
+} /* end module_verify_elf() */
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify.h linux-900/kernel/module-verify.h
--- linux-811/kernel/module-verify.h
+++ linux-900/kernel/module-verify.h
@@ -0,0 +1,37 @@
+/* module-verify.h: module verification definitions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+#include <asm/module.h>
+
+struct module_verify_data {
+	struct crypto_tfm	*digest;	/* module signature digest */
+	const void		*buffer;	/* module buffer */
+	const Elf_Ehdr		*hdr;		/* ELF header */
+	const Elf_Shdr		*sections;	/* ELF section table */
+	const Elf_Sym		*symbols;	/* ELF symbol table */
+	const char		*secstrings;	/* ELF section string table */
+	const char		*strings;	/* ELF string table */
+	size_t			*secsizes;	/* section size list */
+	size_t			size;		/* module object size */
+	size_t			nsects;		/* number of sections */
+	size_t			nsyms;		/* number of symbols */
+	size_t			nstrings;	/* size of strings section */
+	size_t			signed_size;	/* count of bytes contributed to digest */
+	int			*canonlist;	/* list of canonicalised sections */
+	int			*canonmap;	/* section canonicalisation map */
+	int			sig_index;	/* module signature section index */
+	uint8_t			xcsum;		/* checksum of bytes contributed to digest */
+	uint8_t			csum;		/* checksum of bytes representing a section */
+};
+
+extern int module_verify(const Elf_Ehdr *hdr, size_t size);
+extern int module_verify_signature(struct module_verify_data *mvdata);
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify-sig.c linux-900/kernel/module-verify-sig.c
--- linux-811/kernel/module-verify-sig.c
+++ linux-900/kernel/module-verify-sig.c
@@ -0,0 +1,442 @@
+/* module-verify-sig.c: module signature checker
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ * - Derived from GregKH's RSA module signer
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/elf.h>
+#include <linux/crypto.h>
+#include <linux/crypto/ksign.h>
+#include "module-verify.h"
+
+#undef MODSIGN_DEBUG
+
+#ifdef MODSIGN_DEBUG
+#define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__)
+#else
+#define _debug(FMT, ...) do {} while (0)
+#endif
+
+#ifdef MODSIGN_DEBUG
+#define count_and_csum(C, __p,__n)			\
+do {							\
+	int __loop;					\
+	for (__loop = 0; __loop < __n; __loop++) {	\
+		(C)->csum += __p[__loop];		\
+		(C)->xcsum += __p[__loop];		\
+	}						\
+	(C)->signed_size += __n;			\
+} while(0)
+#else
+#define count_and_csum(C, __p,__n)		\
+do {						\
+	(C)->signed_size += __n;		\
+} while(0)
+#endif
+
+#define crypto_digest_update_data(C,PTR,N)			\
+do {								\
+	size_t __n = (N);					\
+	uint8_t *__p = (uint8_t *)(PTR);			\
+	count_and_csum((C), __p, __n);				\
+	crypto_digest_update_kernel((C)->digest, __p, __n);	\
+} while(0)
+
+#define crypto_digest_update_val(C,VAL)				\
+do {								\
+	size_t __n = sizeof(VAL);				\
+	uint8_t *__p = (uint8_t *)&(VAL);			\
+	count_and_csum((C), __p, __n);				\
+	crypto_digest_update_kernel((C)->digest, __p, __n);	\
+} while(0)
+
+static int module_verify_canonicalise(struct module_verify_data *mvdata);
+
+static int extract_elf_rela(struct module_verify_data *mvdata,
+			    int secix,
+			    const Elf_Rela *relatab, size_t nrels,
+			    const char *sh_name);
+
+static int extract_elf_rel(struct module_verify_data *mvdata,
+			   int secix,
+			   const Elf_Rel *reltab, size_t nrels,
+			   const char *sh_name);
+
+static int signedonly;
+
+/*****************************************************************************/
+/*
+ * verify a module's signature
+ */
+int module_verify_signature(struct module_verify_data *mvdata)
+{
+	const Elf_Shdr *sechdrs = mvdata->sections;
+	const char *secstrings = mvdata->secstrings;
+	const char *sig;
+	unsigned sig_size;
+	int i, ret;
+
+	for (i = 1; i < mvdata->nsects; i++) {
+		switch (sechdrs[i].sh_type) {
+		case SHT_PROGBITS:
+			if (strcmp(mvdata->secstrings + sechdrs[i].sh_name,
+				   ".module_sig") == 0) {
+				mvdata->sig_index = i;
+			}
+			break;
+		}
+	}
+
+	if (mvdata->sig_index <= 0)
+		goto no_signature;
+
+	sig = mvdata->buffer + sechdrs[mvdata->sig_index].sh_offset;
+	sig_size = sechdrs[mvdata->sig_index].sh_size;
+
+	_debug("sig in section %d (size %d)\n",
+	       mvdata->sig_index, sig_size);
+
+	/* produce a canonicalisation map for the sections */
+	ret = module_verify_canonicalise(mvdata);
+	if (ret < 0)
+		return ret;
+
+	/* grab an SHA1 transformation context
+	 * - !!! if this tries to load the sha1.ko module, we will deadlock!!!
+	 */
+	mvdata->digest = crypto_alloc_tfm2("sha1", 0, 1);
+	if (!mvdata->digest) {
+		printk("Couldn't load module - SHA1 transform unavailable\n");
+		return -EPERM;
+	}
+
+	crypto_digest_init(mvdata->digest);
+
+#ifdef MODSIGN_DEBUG
+	mvdata->xcsum = 0;
+#endif
+
+	/* load data from each relevant section into the digest */
+	for (i = 1; i < mvdata->nsects; i++) {
+		unsigned long sh_type = sechdrs[i].sh_type;
+		unsigned long sh_info = sechdrs[i].sh_info;
+		unsigned long sh_size = sechdrs[i].sh_size;
+		unsigned long sh_flags = sechdrs[i].sh_flags;
+		const char *sh_name = secstrings + sechdrs[i].sh_name;
+		const void *data = mvdata->buffer + sechdrs[i].sh_offset;
+
+		if (i == mvdata->sig_index)
+			continue;
+
+#ifdef MODSIGN_DEBUG
+		mvdata->csum = 0;
+#endif
+
+		/* it would be nice to include relocation sections, but the act
+		 * of adding a signature to the module seems changes their
+		 * contents, because the symtab gets changed when sections are
+		 * added or removed */
+		if (sh_type == SHT_REL || sh_type == SHT_RELA) {
+			if (mvdata->canonlist[sh_info]) {
+				uint32_t xsh_info = mvdata->canonmap[sh_info];
+
+				crypto_digest_update_data(mvdata, sh_name, strlen(sh_name));
+				crypto_digest_update_val(mvdata, sechdrs[i].sh_type);
+				crypto_digest_update_val(mvdata, sechdrs[i].sh_flags);
+				crypto_digest_update_val(mvdata, sechdrs[i].sh_size);
+				crypto_digest_update_val(mvdata, sechdrs[i].sh_addralign);
+				crypto_digest_update_val(mvdata, xsh_info);
+
+				if (sh_type == SHT_RELA)
+					ret = extract_elf_rela(
+						mvdata, i,
+						data,
+						sh_size / sizeof(Elf_Rela),
+						sh_name);
+				else
+					ret = extract_elf_rel(
+						mvdata, i,
+						data,
+						sh_size / sizeof(Elf_Rel),
+						sh_name);
+
+				if (ret < 0)
+					goto format_error;
+			}
+
+			continue;
+		}
+
+		/* include allocatable loadable sections */
+		if (sh_type != SHT_NOBITS && sh_flags & SHF_ALLOC)
+			goto include_section;
+
+		continue;
+
+	include_section:
+		crypto_digest_update_data(mvdata, sh_name, strlen(sh_name));
+		crypto_digest_update_val(mvdata, sechdrs[i].sh_type);
+		crypto_digest_update_val(mvdata, sechdrs[i].sh_flags);
+		crypto_digest_update_val(mvdata, sechdrs[i].sh_size);
+		crypto_digest_update_val(mvdata, sechdrs[i].sh_addralign);
+		crypto_digest_update_data(mvdata, data, sh_size);
+
+		_debug("%08zx %02x digested the %s section, size %ld\n",
+		       mvdata->signed_size, mvdata->csum, sh_name, sh_size);
+
+		mvdata->canonlist[i] = 1;
+	}
+
+	_debug("Contributed %zu bytes to the digest (csum 0x%02x)\n",
+	       mvdata->signed_size, mvdata->xcsum);
+
+	/* do the actual signature verification */
+	i = ksign_verify_signature(sig, sig_size, mvdata->digest);
+
+	_debug("verify-sig : %d\n", i);
+
+	if (i == 0)
+		i = 1;
+	return i;
+
+ format_error:
+	crypto_free_tfm(mvdata->digest);
+	return -ELIBBAD;
+
+	/* deal with the case of an unsigned module */
+ no_signature:
+ 	if (!signedonly)
+		return 0;
+	printk("An attempt to load unsigned module was rejected\n");
+	return -EPERM;
+
+} /* end module_verify_signature() */
+
+/*****************************************************************************/
+/*
+ * canonicalise the section table index numbers
+ */
+static int module_verify_canonicalise(struct module_verify_data *mvdata)
+{
+	int canon, loop, changed, tmp;
+
+	/* produce a list of index numbers of sections that contribute
+	 * to the kernel's module image
+	 */
+	mvdata->canonlist =
+		kmalloc(sizeof(int) * mvdata->nsects * 2, GFP_KERNEL);
+	if (!mvdata->canonlist)
+		return -ENOMEM;
+
+	mvdata->canonmap = mvdata->canonlist + mvdata->nsects;
+	canon = 0;
+
+	for (loop = 1; loop < mvdata->nsects; loop++) {
+		const Elf_Shdr *section = mvdata->sections + loop;
+
+		if (loop != mvdata->sig_index) {
+			/* we only need to canonicalise allocatable sections */
+			if (section->sh_flags & SHF_ALLOC)
+				mvdata->canonlist[canon++] = loop;
+		}
+	}
+
+	/* canonicalise the index numbers of the contributing section */
+	do {
+		changed = 0;
+
+		for (loop = 0; loop < canon - 1; loop++) {
+			const char *x, *y;
+
+			x = mvdata->secstrings +
+				mvdata->sections[mvdata->canonlist[loop + 0]].sh_name;
+			y = mvdata->secstrings +
+				mvdata->sections[mvdata->canonlist[loop + 1]].sh_name;
+
+			if (strcmp(x, y) > 0) {
+				tmp = mvdata->canonlist[loop + 0];
+				mvdata->canonlist[loop + 0] =
+					mvdata->canonlist[loop + 1];
+				mvdata->canonlist[loop + 1] = tmp;
+				changed = 1;
+			}
+		}
+
+	} while(changed);
+
+	for (loop = 0; loop < canon; loop++)
+		mvdata->canonmap[mvdata->canonlist[loop]] = loop + 1;
+
+	return 0;
+
+} /* end module_verify_canonicalise() */
+
+/*****************************************************************************/
+/*
+ * extract a RELA table
+ * - need to canonicalise the entries in case section addition/removal has
+ *   rearranged the symbol table and the section table
+ */
+static int extract_elf_rela(struct module_verify_data *mvdata,
+			    int secix,
+			    const Elf_Rela *relatab, size_t nrels,
+			    const char *sh_name)
+{
+	struct {
+#if defined(MODULES_ARE_ELF32)
+		uint32_t	r_offset;
+		uint32_t	r_addend;
+		uint32_t	st_value;
+		uint32_t	st_size;
+		uint16_t	st_shndx;
+		uint8_t		r_type;
+		uint8_t		st_info;
+		uint8_t		st_other;
+#elif defined(MODULES_ARE_ELF64)
+		uint64_t	r_offset;
+		uint64_t	r_addend;
+		uint64_t	st_value;
+		uint64_t	st_size;
+		uint32_t	r_type;
+		uint16_t	st_shndx;
+		uint8_t		st_info;
+		uint8_t		st_other;
+#else
+#error unsupported module type
+#endif
+	} __attribute__((packed)) relocation;
+
+	const Elf_Rela *reloc;
+	const Elf_Sym *symbol;
+	size_t loop;
+
+	/* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+	for (loop = 0; loop < nrels; loop++) {
+		int st_shndx;
+
+		reloc = &relatab[loop];
+
+		/* decode the relocation */
+		relocation.r_offset = reloc->r_offset;
+		relocation.r_addend = reloc->r_addend;
+		relocation.r_type = ELF_R_TYPE(reloc->r_info);
+
+		/* decode the symbol referenced by the relocation */
+		symbol = &mvdata->symbols[ELF_R_SYM(reloc->r_info)];
+		relocation.st_info = symbol->st_info;
+		relocation.st_other = symbol->st_other;
+		relocation.st_value = symbol->st_value;
+		relocation.st_size = symbol->st_size;
+		relocation.st_shndx = symbol->st_shndx;
+		st_shndx = symbol->st_shndx;
+
+		/* canonicalise the section used by the symbol */
+		if (st_shndx > SHN_UNDEF && st_shndx < mvdata->nsects)
+			relocation.st_shndx = mvdata->canonmap[st_shndx];
+
+		crypto_digest_update_val(mvdata, relocation);
+
+		/* undefined symbols must be named if referenced */
+		if (st_shndx == SHN_UNDEF) {
+			const char *name = mvdata->strings + symbol->st_name;
+			crypto_digest_update_data(mvdata,
+						  name, strlen(name) + 1);
+		}
+	}
+
+	_debug("%08zx %02x digested the %s section, nrels %zu\n",
+	       mvdata->signed_size, mvdata->csum, sh_name, nrels);
+
+	return 0;
+} /* end extract_elf_rela() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static int extract_elf_rel(struct module_verify_data *mvdata,
+			   int secix,
+			   const Elf_Rel *reltab, size_t nrels,
+			   const char *sh_name)
+{
+	struct {
+#if defined(MODULES_ARE_ELF32)
+		uint32_t	r_offset;
+		uint32_t	st_value;
+		uint32_t	st_size;
+		uint16_t	st_shndx;
+		uint8_t		r_type;
+		uint8_t		st_info;
+		uint8_t		st_other;
+#elif defined(MODULES_ARE_ELF64)
+		uint64_t	r_offset;
+		uint64_t	st_value;
+		uint64_t	st_size;
+		uint32_t	r_type;
+		uint16_t	st_shndx;
+		uint8_t		st_info;
+		uint8_t		st_other;
+#else
+#error unsupported module type
+#endif
+	} __attribute__((packed)) relocation;
+
+	const Elf_Rel *reloc;
+	const Elf_Sym *symbol;
+	size_t loop;
+
+	/* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+	for (loop = 0; loop < nrels; loop++) {
+		int st_shndx;
+
+		reloc = &reltab[loop];
+
+		/* decode the relocation */
+		relocation.r_offset = reloc->r_offset;
+		relocation.r_type = ELF_R_TYPE(reloc->r_info);
+
+		/* decode the symbol referenced by the relocation */
+		symbol = &mvdata->symbols[ELF_R_SYM(reloc->r_info)];
+		relocation.st_info = symbol->st_info;
+		relocation.st_other = symbol->st_other;
+		relocation.st_value = symbol->st_value;
+		relocation.st_size = symbol->st_size;
+		relocation.st_shndx = symbol->st_shndx;
+		st_shndx = symbol->st_shndx;
+
+		/* canonicalise the section used by the symbol */
+		if (st_shndx > SHN_UNDEF && st_shndx < mvdata->nsects)
+			relocation.st_shndx = mvdata->canonmap[st_shndx];
+
+		crypto_digest_update_val(mvdata, relocation);
+
+		/* undefined symbols must be named if referenced */
+		if (st_shndx == SHN_UNDEF) {
+			const char *name = mvdata->strings + symbol->st_name;
+			crypto_digest_update_data(mvdata,
+						  name, strlen(name) + 1);
+		}
+	}
+
+	_debug("%08zx %02x digested the %s section, nrels %zu\n",
+	       mvdata->signed_size, mvdata->csum, sh_name, nrels);
+
+	return 0;
+} /* end extract_elf_rel() */
+
+static int __init sign_setup(char *str)
+{
+	signedonly = 1;
+	return 0;
+}
+__setup("enforcemodulesig", sign_setup);
--- linux-2.6.12/kernel/module-verify.c.~1~	2005-08-07 17:39:38.000000000 -0700
+++ linux-2.6.12/kernel/module-verify.c	2005-08-10 00:48:43.000000000 -0700
@@ -107,7 +107,7 @@ do { if (unlikely(!(X))) { line = __LINE
 	elfcheck(hdr->e_shentsize == sizeof(Elf_Shdr));
 
 	tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
-	elfcheck(tmp < size - hdr->e_shoff);
+	elfcheck(tmp <= size - hdr->e_shoff);
 
 	/* allocate a table to hold in-file section sizes */
 	mvdata->secsizes = kmalloc(hdr->e_shnum * sizeof(size_t), GFP_KERNEL);


linux-2.6-modsign-crypto.patch:
 crypto/Kconfig         |   19 +++++++++++++++++++
 crypto/Makefile        |    3 +++
 crypto/api.c           |   16 ++++++++++++++--
 include/linux/crypto.h |    4 ++++
 4 files changed, 40 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-modsign-crypto.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/api.c linux-901/crypto/api.c
--- linux-900/crypto/api.c
+++ linux-901/crypto/api.c
@@ -117,12 +117,19 @@ static void crypto_exit_ops(struct crypt
 	}
 }
 
-struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+struct crypto_tfm *crypto_alloc_tfm2(const char *name, u32 flags,
+				     int nomodload)
 {
 	struct crypto_tfm *tfm = NULL;
 	struct crypto_alg *alg;
 	unsigned int tfm_size;
 
-	alg = crypto_alg_mod_lookup(name);
+	if (!nomodload) {
+		alg = crypto_alg_mod_lookup(name);
+	}
+	else {
+		alg = crypto_alg_lookup(name);
+	}
+
 	if (alg == NULL)
 		goto out;
@@ -153,6 +160,11 @@ out:
 	return tfm;
 }
 
+struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+{
+	return crypto_alloc_tfm2(name, flags, 0);
+}
+
 void crypto_free_tfm(struct crypto_tfm *tfm)
 {
 	struct crypto_alg *alg = tfm->__crt_alg;
diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/Kconfig linux-901/crypto/Kconfig
--- linux-900/crypto/Kconfig
+++ linux-901/crypto/Kconfig
@@ -287,6 +287,25 @@ config CRYPTO_TEST
 	help
 	  Quick & dirty crypto test module.
 
+config CRYPTO_SIGNATURE
+	bool "In-kernel signature checker (EXPERIMENTAL)"
+	depends on CRYPTO
+	help
+	  Signature checker (used for module sig checking).
+
+config CRYPTO_SIGNATURE_DSA
+	bool "Handle DSA signatures (EXPERIMENTAL)"
+	depends on CRYPTO_SIGNATURE
+	select CRYPTO_MPILIB
+	help
+	  DSA Signature checker.
+
+config CRYPTO_MPILIB
+	bool "Multiprecision maths library (EXPERIMENTAL)"
+	depends on CRYPTO
+	help
+	  Multiprecision maths library from GnuPG
+
 source "drivers/crypto/Kconfig"
 endmenu
 
diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/Makefile linux-901/crypto/Makefile
--- linux-900/crypto/Makefile
+++ linux-901/crypto/Makefile
@@ -32,3 +32,6 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += mich
 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
 
 obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
+
+obj-$(CONFIG_CRYPTO_SIGNATURE) += signature/
+obj-$(CONFIG_CRYPTO_MPILIB) += mpi/
diff -urNp --exclude-from=/home/davej/.exclude linux-900/include/linux/crypto.h linux-901/include/linux/crypto.h
--- linux-900/include/linux/crypto.h
+++ linux-901/include/linux/crypto.h
@@ -213,10 +213,14 @@ struct crypto_tfm {
  * will then attempt to load a module of the same name or alias.  A refcount
  * is grabbed on the algorithm which is then associated with the new transform.
  *
+ * crypto_alloc_tfm2() is similar, but allows module loading to be suppressed.
+ *
  * crypto_free_tfm() frees up the transform and any associated resources,
  * then drops the refcount on the associated algorithm.
  */
 struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
+struct crypto_tfm *crypto_alloc_tfm2(const char *alg_name, u32 tfm_flags,
+				     int nomodload);
 void crypto_free_tfm(struct crypto_tfm *tfm);
 
 /*

linux-2.6-modsign-include.patch:
 linux-2.6.13/include/asm-powerpc/module.h |   10 ++++++++++
 linux-2.6.14/include/asm-mips/module.h    |   12 ++++++++++--
 linux-905/include/asm-alpha/module.h      |    3 +++
 linux-905/include/asm-arm/module.h        |    5 +++++
 linux-905/include/asm-cris/module.h       |    5 +++++
 linux-905/include/asm-h8300/module.h      |    5 +++++
 linux-905/include/asm-i386/module.h       |    5 +++++
 linux-905/include/asm-ia64/module.h       |    5 +++++
 linux-905/include/asm-m32r/module.h       |    5 +++++
 linux-905/include/asm-m68k/module.h       |    5 +++++
 linux-905/include/asm-parisc/module.h     |    8 ++++++++
 linux-905/include/asm-s390/module.h       |    3 +++
 linux-905/include/asm-sh/module.h         |    5 +++++
 linux-905/include/asm-sparc/module.h      |    5 +++++
 linux-905/include/asm-sparc64/module.h    |    5 +++++
 linux-905/include/asm-um/module-i386.h    |    4 ++++
 linux-905/include/asm-v850/module.h       |    5 +++++
 linux-905/include/asm-x86_64/module.h     |    5 +++++
 18 files changed, 98 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-modsign-include.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-alpha/module.h linux-905/include/asm-alpha/module.h
--- linux-904/include/asm-alpha/module.h
+++ linux-905/include/asm-alpha/module.h
@@ -6,6 +6,7 @@ struct mod_arch_specific
 	unsigned int gotsecindex;
 };
 
+#define MODULES_ARE_ELF64
 #define Elf_Sym Elf64_Sym
 #define Elf_Shdr Elf64_Shdr
 #define Elf_Ehdr Elf64_Ehdr
@@ -13,6 +14,8 @@ struct mod_arch_specific
 #define Elf_Dyn Elf64_Dyn
 #define Elf_Rel Elf64_Rel
 #define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X)	ELF64_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF64_R_SYM(X)
 
 #define ARCH_SHF_SMALL SHF_ALPHA_GPREL
 
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-arm/module.h linux-905/include/asm-arm/module.h
--- linux-904/include/asm-arm/module.h
+++ linux-905/include/asm-arm/module.h
@@ -6,9 +6,14 @@ struct mod_arch_specific
 	int foo;
 };
 
+#define MODULES_ARE_ELF32
 #define Elf_Shdr	Elf32_Shdr
 #define Elf_Sym		Elf32_Sym
 #define Elf_Ehdr	Elf32_Ehdr
+#define Elf_Rel		Elf32_Rel
+#define Elf_Rela	Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 
 /*
  * Include the ARM architecture version.
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-cris/module.h linux-905/include/asm-cris/module.h
--- linux-904/include/asm-cris/module.h
+++ linux-905/include/asm-cris/module.h
@@ -3,7 +3,12 @@
 /* cris is simple */
 struct mod_arch_specific { };
 
+#define MODULES_ARE_ELF32
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 #endif /* _ASM_CRIS_MODULE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-h8300/module.h linux-905/include/asm-h8300/module.h
--- linux-904/include/asm-h8300/module.h
+++ linux-905/include/asm-h8300/module.h
@@ -4,9 +4,14 @@
  * This file contains the H8/300 architecture specific module code.
  */
 struct mod_arch_specific { };
+#define MODULES_ARE_ELF32
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 
 #define MODULE_SYMBOL_PREFIX "_"
 
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-i386/module.h linux-905/include/asm-i386/module.h
--- linux-904/include/asm-i386/module.h
+++ linux-905/include/asm-i386/module.h
@@ -6,9 +6,14 @@ struct mod_arch_specific
 {
 };
 
+#define MODULES_ARE_ELF32
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 
 #ifdef CONFIG_M386
 #define MODULE_PROC_FAMILY "386 "
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-ia64/module.h linux-905/include/asm-ia64/module.h
--- linux-904/include/asm-ia64/module.h
+++ linux-905/include/asm-ia64/module.h
@@ -23,9 +23,14 @@ struct mod_arch_specific {
 	unsigned int next_got_entry;	/* index of next available got entry */
 };
 
+#define MODULES_ARE_ELF64
 #define Elf_Shdr	Elf64_Shdr
 #define Elf_Sym		Elf64_Sym
 #define Elf_Ehdr	Elf64_Ehdr
+#define Elf_Rel		Elf64_Rel
+#define Elf_Rela	Elf64_Rela
+#define ELF_R_TYPE(X)	ELF64_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF64_R_SYM(X)
 
 #define MODULE_PROC_FAMILY	"ia64"
 #define MODULE_ARCH_VERMAGIC	MODULE_PROC_FAMILY
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-m32r/module.h linux-905/include/asm-m32r/module.h
--- linux-904/include/asm-m32r/module.h
+++ linux-905/include/asm-m32r/module.h
@@ -5,9 +5,14 @@
 
 struct mod_arch_specific { };
 
+#define MODULES_ARE_ELF32
 #define Elf_Shdr	Elf32_Shdr
 #define Elf_Sym		Elf32_Sym
 #define Elf_Ehdr	Elf32_Ehdr
+#define Elf_Rel		Elf32_Rel
+#define Elf_Rela	Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 
 #endif /* _ASM_M32R_MODULE_H */
 
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-m68k/module.h linux-905/include/asm-m68k/module.h
--- linux-904/include/asm-m68k/module.h
+++ linux-905/include/asm-m68k/module.h
@@ -1,7 +1,12 @@
 #ifndef _ASM_M68K_MODULE_H
 #define _ASM_M68K_MODULE_H
 struct mod_arch_specific { };
+#define MODULES_ARE_ELF32
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 #endif /* _ASM_M68K_MODULE_H */

--- linux-2.6.14/include/asm-mips/module.h~	2005-10-30 21:31:42.000000000 -0500
+++ linux-2.6.14/include/asm-mips/module.h	2005-10-30 21:33:30.000000000 -0500
@@ -34,11 +34,15 @@ typedef struct {
 } Elf64_Mips_Rela;
 
 #ifdef CONFIG_32BIT
-
+#define MODULES_ARE_ELF32
 #define Elf_Shdr	Elf32_Shdr
 #define Elf_Sym		Elf32_Sym
 #define Elf_Ehdr	Elf32_Ehdr
 #define Elf_Addr	Elf32_Addr
+#define Elf_Rel		Elf32_Rel
+#define Elf_Rela	Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 
 #define Elf_Mips_Rel	Elf32_Rel
 #define Elf_Mips_Rela	Elf32_Rela
@@ -49,11 +53,15 @@ typedef struct {
 #endif
 
 #ifdef CONFIG_64BIT
-
+#define MODULES_ARE_ELF64
 #define Elf_Shdr	Elf64_Shdr
 #define Elf_Sym		Elf64_Sym
 #define Elf_Ehdr	Elf64_Ehdr
 #define Elf_Addr	Elf64_Addr
+#define Elf_Rel		Elf64_Rel
+#define Elf_Rela	Elf64_Rela
+#define ELF_R_TYPE(X)	ELF64_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF64_R_SYM(X)
 
 #define Elf_Mips_Rel	Elf64_Mips_Rel
 #define Elf_Mips_Rela	Elf64_Mips_Rela
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-parisc/module.h linux-905/include/asm-parisc/module.h
--- linux-904/include/asm-parisc/module.h
+++ linux-905/include/asm-parisc/module.h
@@ -4,17 +4,25 @@
  * This file contains the parisc architecture specific module code.
  */
 #ifdef __LP64__
+#define MODULES_ARE_ELF64
 #define Elf_Shdr Elf64_Shdr
 #define Elf_Sym Elf64_Sym
 #define Elf_Ehdr Elf64_Ehdr
 #define Elf_Addr Elf64_Addr
+#define Elf_Rel Elf64_Rel
 #define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X)	ELF64_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF64_R_SYM(X)
 #else
+#define MODULES_ARE_ELF32
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
 #define Elf_Addr Elf32_Addr
+#define Elf_Rel Elf32_Rel
 #define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 #endif
 
 struct unwind_table;
--- linux-2.6.13/include/asm-powerpc/module.h~	2005-09-08 01:05:31.000000000 -0400
+++ linux-2.6.13/include/asm-powerpc/module.h	2005-09-08 01:11:30.000000000 -0400
@@ -53,16 +53,26 @@ extern struct bug_entry *module_find_bug
  */
 
 #ifdef __powerpc64__
+#    define MODULES_ARE_ELF64
 #    define Elf_Shdr	Elf64_Shdr
 #    define Elf_Sym	Elf64_Sym
 #    define Elf_Ehdr	Elf64_Ehdr
+#    define Elf_Rel Elf64_Rel
+#    define Elf_Rela Elf64_Rela
+#    define ELF_R_TYPE(X)	ELF64_R_TYPE(X)
+#    define ELF_R_SYM(X)	ELF64_R_SYM(X)
 #    ifdef MODULE
 	asm(".section .stubs,\"ax\", at nobits; .align 3; .previous");
 #    endif
 #else
+#    define MODULES_ARE_ELF32
 #    define Elf_Shdr	Elf32_Shdr
 #    define Elf_Sym	Elf32_Sym
 #    define Elf_Ehdr	Elf32_Ehdr
+#    define Elf_Rel Elf32_Rel
+#    define Elf_Rela Elf32_Rela
+#    define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#    define ELF_R_SYM(X)	ELF32_R_SYM(X)
 #    ifdef MODULE
 	asm(".section .plt,\"ax\", at nobits; .align 3; .previous");
 	asm(".section .init.plt,\"ax\", at nobits; .align 3; .previous");
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-s390/module.h linux-905/include/asm-s390/module.h
--- linux-904/include/asm-s390/module.h
+++ linux-905/include/asm-s390/module.h
@@ -29,14 +29,17 @@ struct mod_arch_specific
 };
 
 #ifdef __s390x__
+#define MODULES_ARE_ELF64
 #define ElfW(x) Elf64_ ## x
 #define ELFW(x) ELF64_ ## x
 #else
+#define MODULES_ARE_ELF32
 #define ElfW(x) Elf32_ ## x
 #define ELFW(x) ELF32_ ## x
 #endif
 
 #define Elf_Addr ElfW(Addr)
+#define Elf_Rel ElfW(Rel)
 #define Elf_Rela ElfW(Rela)
 #define Elf_Shdr ElfW(Shdr)
 #define Elf_Sym ElfW(Sym)
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sh/module.h linux-905/include/asm-sh/module.h
--- linux-904/include/asm-sh/module.h
+++ linux-905/include/asm-sh/module.h
@@ -9,9 +9,14 @@ struct mod_arch_specific {
 	/* Nothing to see here .. */
 };
 
+#define MODULES_ARE_ELF32
 #define Elf_Shdr		Elf32_Shdr
 #define Elf_Sym			Elf32_Sym
 #define Elf_Ehdr		Elf32_Ehdr
+#define Elf_Rel			Elf32_Rel
+#define Elf_Rela		Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
 # ifdef CONFIG_CPU_SH2
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sparc/module.h linux-905/include/asm-sparc/module.h
--- linux-904/include/asm-sparc/module.h
+++ linux-905/include/asm-sparc/module.h
@@ -1,7 +1,12 @@
 #ifndef _ASM_SPARC_MODULE_H
 #define _ASM_SPARC_MODULE_H
 struct mod_arch_specific { };
+#define MODULES_ARE_ELF32
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 #endif /* _ASM_SPARC_MODULE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sparc64/module.h linux-905/include/asm-sparc64/module.h
--- linux-904/include/asm-sparc64/module.h
+++ linux-905/include/asm-sparc64/module.h
@@ -1,7 +1,12 @@
 #ifndef _ASM_SPARC64_MODULE_H
 #define _ASM_SPARC64_MODULE_H
 struct mod_arch_specific { };
+#define MODULES_ARE_ELF64
 #define Elf_Shdr Elf64_Shdr
 #define Elf_Sym Elf64_Sym
 #define Elf_Ehdr Elf64_Ehdr
+#define Elf_Rel Elf64_Rel
+#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X)	ELF64_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF64_R_SYM(X)
 #endif /* _ASM_SPARC64_MODULE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-um/module-i386.h linux-905/include/asm-um/module-i386.h
--- linux-904/include/asm-um/module-i386.h
+++ linux-905/include/asm-um/module-i386.h
@@ -9,5 +9,9 @@ struct mod_arch_specific
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-v850/module.h linux-905/include/asm-v850/module.h
--- linux-904/include/asm-v850/module.h
+++ linux-905/include/asm-v850/module.h
@@ -31,9 +31,14 @@ struct mod_arch_specific
 	unsigned int core_plt_section, init_plt_section;
 };
 
+#define MODULES_ARE_ELF32
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF32_R_SYM(X)
 
 /* Make empty sections for module_frob_arch_sections to expand. */
 #ifdef MODULE
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-x86_64/module.h linux-905/include/asm-x86_64/module.h
--- linux-904/include/asm-x86_64/module.h
+++ linux-905/include/asm-x86_64/module.h
@@ -3,8 +3,13 @@
 
 struct mod_arch_specific {}; 
 
+#define MODULES_ARE_ELF64
 #define Elf_Shdr Elf64_Shdr
 #define Elf_Sym Elf64_Sym
 #define Elf_Ehdr Elf64_Ehdr
+#define Elf_Rel Elf64_Rel
+#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X)	ELF64_R_TYPE(X)
+#define ELF_R_SYM(X)	ELF64_R_SYM(X)
 
 #endif 

linux-2.6-modsign-ksign.patch:
 linux-2.6.14/crypto/signature/ksign-keyring.c |    2 
 linux-902/crypto/digest.c                     |    8 
 linux-902/crypto/signature/Makefile           |   10 
 linux-902/crypto/signature/dsa.c              |   98 ++++
 linux-902/crypto/signature/key.h              |    7 
 linux-902/crypto/signature/ksign-keyring.c    |  112 ++++
 linux-902/crypto/signature/ksign-parse.c      |  609 ++++++++++++++++++++++++++
 linux-902/crypto/signature/ksign-publickey.c  |   19 
 linux-902/crypto/signature/ksign.c            |  179 +++++++
 linux-902/crypto/signature/local.h            |  163 ++++++
 linux-902/include/linux/crypto.h              |   10 
 linux-902/include/linux/crypto/ksign.h        |   22 
 12 files changed, 1239 insertions(+)

--- NEW FILE linux-2.6-modsign-ksign.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/digest.c linux-902/crypto/digest.c
--- linux-901/crypto/digest.c
+++ linux-902/crypto/digest.c
@@ -52,6 +52,13 @@ static void update(struct crypto_tfm *tf
 	}
 }
 
+static void update_kernel(struct crypto_tfm *tfm,
+			  const void *data, size_t count)
+{
+	tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), data, count);
+	crypto_yield(tfm);
+}
+
 static void final(struct crypto_tfm *tfm, u8 *out)
 {
 	tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
@@ -94,6 +101,7 @@ int crypto_init_digest_ops(struct crypto
 	
 	ops->dit_init	= init;
 	ops->dit_update	= update;
+	ops->dit_update_kernel = update_kernel;
 	ops->dit_final	= final;
 	ops->dit_digest	= digest;
 	ops->dit_setkey	= setkey;
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/dsa.c linux-902/crypto/signature/dsa.c
--- linux-901/crypto/signature/dsa.c
+++ linux-902/crypto/signature/dsa.c
@@ -0,0 +1,98 @@
+/* dsa.c  -  DSA signature algorithm
+ *	Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/crypto/mpi.h>
+#include <asm/errno.h>
+#include "local.h"
+
+/*****************************************************************************/
+/*
+ * perform DSA algorithm signature verification
+ */
+int DSA_verify(const MPI datahash, const MPI sig[], const MPI pkey[])
+{
+	MPI p, q, g, y, r, s;
+	MPI w = NULL, u1 = NULL, u2 = NULL, v = NULL;
+	MPI base[3];
+	MPI exp[3];
+	int rc;
+
+	if (!datahash ||
+	    !sig[0] || !sig[1] ||
+	    !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3]
+	    )
+		return -EINVAL;
+
+	p = pkey[0];	/* prime */
+	q = pkey[1];	/* group order */
+	g = pkey[2];	/* group generator */
+	y = pkey[3];	/* g^x mod p */
+	r = sig[0];
+	s = sig[1];
+
+	if (!(mpi_cmp_ui(r, 0) > 0 && mpi_cmp(r, q) < 0)) {
+		printk("DSA_verify assertion failed [0 < r < q]\n");
+		return -EPERM;
+	}
+
+	if (!(mpi_cmp_ui(s, 0) > 0 && mpi_cmp(s, q) < 0)) {
+		printk("DSA_verify assertion failed [0 < s < q]\n");
+		return -EPERM;
+	}
+
+	rc = -ENOMEM;
+	w  = mpi_alloc(mpi_get_nlimbs(q)); if (!w ) goto cleanup;
+	u1 = mpi_alloc(mpi_get_nlimbs(q)); if (!u1) goto cleanup;
+	u2 = mpi_alloc(mpi_get_nlimbs(q)); if (!u2) goto cleanup;
+	v  = mpi_alloc(mpi_get_nlimbs(p)); if (!v ) goto cleanup;
+
+	/* w = s^(-1) mod q */
+	if (mpi_invm(w, s, q) < 0)
+		goto cleanup;
+
+	/* u1 = (datahash * w) mod q */
+	if (mpi_mulm(u1, datahash, w, q) < 0)
+		goto cleanup;
+
+	/* u2 = r * w mod q  */
+	if (mpi_mulm(u2, r, w, q) < 0)
+		goto cleanup;
+
+	/* v =  g^u1 * y^u2 mod p mod q */
+	base[0] = g;	exp[0] = u1;
+	base[1] = y;	exp[1] = u2;
+	base[2] = NULL;	exp[2] = NULL;
+
+	if (mpi_mulpowm(v, base, exp, p) < 0)
+		goto cleanup;
+
+	if (mpi_fdiv_r(v, v, q) < 0)
+		goto cleanup;
+
+	rc = mpi_cmp(v, r) == 0 ? 0 : -EPERM;
+
+ cleanup:
+	mpi_free(w);
+	mpi_free(u1);
+	mpi_free(u2);
+	mpi_free(v);
+	return rc;
+} /* end DSA_verify() */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/key.h linux-902/crypto/signature/key.h
--- linux-901/crypto/signature/key.h
+++ linux-902/crypto/signature/key.h
@@ -0,0 +1,7 @@
+const int ksign_def_public_key_size = 0;
+/* automatically generated by bin2hex */
+static unsigned char ksign_def_public_key[] __initdata =
+{
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign.c linux-902/crypto/signature/ksign.c
--- linux-901/crypto/signature/ksign.c
+++ linux-902/crypto/signature/ksign.c
@@ -0,0 +1,179 @@
+/* ksign.c: signature checker
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <asm/errno.h>
+#include "local.h"
+
+#if 0
+#define _debug(FMT, ...) printk(KERN_DEBUG FMT, ##__VA_ARGS__)
+#else
+#define _debug(FMT, ...) do { ; } while (0)
+#endif
+
+/*****************************************************************************/
+/*
+ * check the signature which is contained in SIG.
+ */
+static int ksign_signature_check(const struct ksign_signature *sig,
+				 struct crypto_tfm *sha1_tfm)
+{
+	struct ksign_public_key *pk;
+	uint8_t sha1[SHA1_DIGEST_SIZE];
+	MPI result = NULL;
+	int rc = 0;
+
+	pk = ksign_get_public_key(sig->keyid);
+	if (!pk) {
+		printk("ksign: module signed with unknown public key\n");
+		printk("- signature keyid: %08x%08x ver=%u\n",
+		       sig->keyid[0], sig->keyid[1], sig->version);
+		return -EPERM;
+	}
+
+	if (pk->timestamp > sig->timestamp)
+		printk("ksign:"
+		       " public key is %lu seconds newer than the signature\n",
+		       pk->timestamp - sig->timestamp);
+
+	/* complete the digest */
+	if (sig->version >= 4)
+		SHA1_putc(sha1_tfm, sig->version);
+	SHA1_putc(sha1_tfm, sig->sig_class);
+
+	if (sig->version < 4) {
+		u32 a = sig->timestamp;
+		SHA1_putc(sha1_tfm, (a >> 24) & 0xff);
+		SHA1_putc(sha1_tfm, (a >> 16) & 0xff);
+		SHA1_putc(sha1_tfm, (a >>  8) & 0xff);
+		SHA1_putc(sha1_tfm, (a >>  0) & 0xff);
+	}
+	else {
+		uint8_t buf[6];
+		size_t n;
+		SHA1_putc(sha1_tfm, PUBKEY_ALGO_DSA);
+		SHA1_putc(sha1_tfm, DIGEST_ALGO_SHA1);
+		if (sig->hashed_data) {
+			n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
+			SHA1_write(sha1_tfm, sig->hashed_data, n + 2);
+			n += 6;
+		}
+		else {
+			n = 6;
+		}
+
+		/* add some magic */
+		buf[0] = sig->version;
+		buf[1] = 0xff;
+		buf[2] = n >> 24;
+		buf[3] = n >> 16;
+		buf[4] = n >>  8;
+		buf[5] = n;
+		SHA1_write(sha1_tfm, buf, 6);
+	}
+
+	crypto_digest_final(sha1_tfm, sha1);
+	crypto_free_tfm(sha1_tfm);
+
+
+
+
+
+
+	rc = -ENOMEM;
+	result = mpi_alloc((SHA1_DIGEST_SIZE + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB);
+	if (!result)
+		goto cleanup;
+
+	rc = mpi_set_buffer(result, sha1, SHA1_DIGEST_SIZE, 0);
+	if (rc < 0)
+		goto cleanup;
+
+	rc = DSA_verify(result, sig->data, pk->pkey);
+
+ cleanup:
+	mpi_free(result);
+	ksign_put_public_key(pk);
+
+	return rc;
+} /* end ksign_signature_check() */
+
+/*****************************************************************************/
+/*
+ * examine the signatures that are parsed out of the signature data - we keep
+ * the first one that's appropriate and ignore the rest
+ * - return 0 if signature of interest (sig not freed by caller)
+ * - return 1 if no interest (caller frees)
+ */
+static int ksign_grab_signature(struct ksign_signature *sig, void *fnxdata)
+{
+	struct ksign_signature **_sig = fnxdata;
+
+	if (sig->sig_class != 0x00) {
+		_debug("ksign: standalone signature of class 0x%02x\n",
+		       sig->sig_class);
+		return 1;
+	}
+
+	if (*_sig)
+		return 1;
+
+	*_sig = sig;
+	return 0;
+} /* end ksign_grab_signature() */
+
+/*****************************************************************************/
+/*
+ * verify the signature of some data with one of the kernel's known public keys
+ * - the SHA1 context should be currently open with the signed data digested
+ *   into it so that more data can be appended
+ * - the SHA1 context is finalised and freed before returning
+ */
+int ksign_verify_signature(const char *sigdata, unsigned sig_size,
+			   struct crypto_tfm *sha1)
+{
+	struct ksign_signature *sig = NULL;
+	int retval;
+
+	/* parse the signature data to get the actual signature */
+	retval = ksign_parse_packets(sigdata, sig_size,
+				     &ksign_grab_signature, NULL, NULL,
+				     &sig);
+	if (retval < 0)
+		goto cleanup;
+
+	if (!sig) {
+		printk("Couldn't find valid DSA signature in module\n");
+		return -ENOENT;
+	}
+
+	_debug("signature keyid: %08x%08x ver=%u\n",
+	       sig->keyid[0], sig->keyid[1], sig->version);
+
+	/* check the data SHA1 transformation against the public key */
+	retval = ksign_signature_check(sig, sha1);
+	if (retval == 0) {
+		_debug("ksign: Signature check succeeded\n");
+	}
+	else if (retval != -ENOMEM) {
+		_debug("ksign: Signature check failed\n");
+		retval = -EPERM;
+	}
+	else {
+		_debug("ksign: Signature check ENOMEM\n");
+	}
+
+ cleanup:
+	if (sig)
+		ksign_free_signature(sig);
+
+	return retval;
+} /* end ksign_verify_signature() */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-keyring.c linux-902/crypto/signature/ksign-keyring.c
--- linux-901/crypto/signature/ksign-keyring.c
+++ linux-902/crypto/signature/ksign-keyring.c
@@ -0,0 +1,112 @@
+/* ksign-keyring.c: public key cache
+ *
+ * Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This file is derived from part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <linux/rwsem.h>
+#include "local.h"
+
+static LIST_HEAD(keyring);
+static DECLARE_RWSEM(keyring_sem);
+
+static int add_keyblock_key(struct ksign_public_key *pk, void *data)
+{
+	printk("- Added public key %X%X\n", pk->keyid[0], pk->keyid[1]);
+
+	if (pk->expiredate && pk->expiredate < xtime.tv_sec)
+		printk("  - public key has expired\n");
+
+	if (pk->timestamp > xtime.tv_sec )
+		printk("  - key was been created %lu seconds in future\n",
+		       pk->timestamp - xtime.tv_sec);
+
+	atomic_inc(&pk->count);
+
+	down_write(&keyring_sem);
+	list_add_tail(&pk->link, &keyring);
+	up_write(&keyring_sem);
+
+	return 0;
+}
+
+static int add_keyblock_uid(struct ksign_user_id *uid, void *data)
+{
+	printk("- User ID: %s\n", uid->name);
+	return 1;
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+int ksign_load_keyring_from_buffer(const void *buffer, size_t size)
+{
+    printk("Loading keyring\n");
+
+    return ksign_parse_packets((const uint8_t *) buffer,
+			       size,
+			       NULL,
+			       add_keyblock_key,
+			       add_keyblock_uid,
+			       NULL);
+} /* end ksign_load_keyring_from_buffer() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+struct ksign_public_key *ksign_get_public_key(const uint32_t *keyid)
+{
+	struct ksign_public_key *pk;
+
+	down_read(&keyring_sem);
+
+	list_for_each_entry(pk, &keyring, link) {
+		if (memcmp(pk->keyid, keyid, sizeof(pk->keyid)) == 0) {
+			atomic_inc(&pk->count);
+			goto found;
+		}
+	}
+
+ found:
+	up_read(&keyring_sem);
+
+	return pk;
+} /* end ksign_get_public_key() */
+
+/*****************************************************************************/
+/*
+ * clear the public key keyring
+ */
+void ksign_clear_keyring(void)
+{
+	struct ksign_public_key *pk;
+
+	down_write(&keyring_sem);
+
+	while (!list_empty(&keyring)) {
+		pk = list_entry(keyring.next, struct ksign_public_key, link);
+		list_del(&pk->link);
+
+		ksign_put_public_key(pk);
+	}
+
+	up_write(&keyring_sem);
+} /* end ksign_clear_keyring() */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-parse.c linux-902/crypto/signature/ksign-parse.c
--- linux-901/crypto/signature/ksign-parse.c
+++ linux-902/crypto/signature/ksign-parse.c
@@ -0,0 +1,609 @@
+/* parse-packet.c  - read packets
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/errno.h>
+#include "local.h"
+
+static inline uint32_t buffer_to_u32(const uint8_t *buffer)
+{
+	uint32_t a;
+	a =  *buffer << 24;
+	a |= buffer[1] << 16;
+	a |= buffer[2] << 8;
+	a |= buffer[3];
+	return a;
+}
+
+static inline uint16_t read_16(const uint8_t **datap)
+{
+	uint16_t a;
+	a = *(*datap)++ << 8;
+	a |= *(*datap)++;
+	return a;
+}
+
+static inline uint32_t read_32(const uint8_t **datap)
+{
+	uint32_t a;
+	a =  *(*datap)++ << 24;
+	a |= *(*datap)++ << 16;
+	a |= *(*datap)++ << 8;
+	a |= *(*datap)++;
+	return a;
+}
+
+void ksign_free_signature(struct ksign_signature *sig)
+{
+	int i;
+
+	if (!sig)
+		return;
+
+	for (i = 0; i < DSA_NSIG; i++)
+		mpi_free(sig->data[i]);
+	kfree(sig->hashed_data);
+	kfree(sig->unhashed_data);
+	kfree(sig);
+}
+
+void ksign_free_public_key(struct ksign_public_key *pk)
+{
+	int i;
+
+	if (pk) {
+		for (i = 0; i < DSA_NPKEY; i++)
+			mpi_free(pk->pkey[i]);
+		kfree(pk);
+	}
+}
+
+void ksign_free_user_id(struct ksign_user_id *uid)
+{
+	if (uid)
+		kfree(uid);
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void ksign_calc_pk_keyid(struct crypto_tfm *sha1,
+				struct ksign_public_key *pk)
+{
+	unsigned n;
+	unsigned nb[DSA_NPKEY];
+	unsigned nn[DSA_NPKEY];
+	uint8_t *pp[DSA_NPKEY];
+	uint32_t a32;
+	int i;
+	int npkey = DSA_NPKEY;
+
+	crypto_digest_init(sha1);
+
+	n = pk->version < 4 ? 8 : 6;
+	for (i = 0; i < npkey; i++) {
+		nb[i] = mpi_get_nbits(pk->pkey[i]);
+		pp[i] = mpi_get_buffer( pk->pkey[i], nn + i, NULL);
+		n += 2 + nn[i];
+	}
+
+	SHA1_putc(sha1, 0x99);     /* ctb */
+	SHA1_putc(sha1, n >> 8);   /* 2 uint8_t length header */
+	SHA1_putc(sha1, n);
+
+	if( pk->version < 4)
+		SHA1_putc(sha1, 3);
+	else
+		SHA1_putc(sha1, 4);
+
+	a32 = pk->timestamp;
+	SHA1_putc(sha1, a32 >> 24 );
+	SHA1_putc(sha1, a32 >> 16 );
+	SHA1_putc(sha1, a32 >>  8 );
+	SHA1_putc(sha1, a32 >>  0 );
+
+	if (pk->version < 4) {
+		uint16_t a16;
+
+		if( pk->expiredate )
+			a16 = (uint16_t) ((pk->expiredate - pk->timestamp) / 86400L);
+		else
+			a16 = 0;
+		SHA1_putc(sha1, a16 >> 8);
+		SHA1_putc(sha1, a16 >> 0);
+	}
+
+	SHA1_putc(sha1, PUBKEY_ALGO_DSA);
+
+	for (i = 0; i < npkey; i++) {
+		SHA1_putc(sha1, nb[i] >> 8);
+		SHA1_putc(sha1, nb[i]);
+		SHA1_write(sha1, pp[i], nn[i]);
+		kfree(pp[i]);
+	}
+
+} /* end ksign_calc_pk_keyid() */
+
+/*****************************************************************************/
+/*
+ * parse a user ID embedded in a signature
+ */
+static int ksign_parse_user_id(const uint8_t *datap, const uint8_t *endp,
+			       ksign_user_id_actor_t uidfnx, void *fnxdata)
+{
+	struct ksign_user_id *uid;
+	int rc = 0;
+	int n;
+
+	if (!uidfnx)
+		return 0;
+
+	n = endp - datap;
+	uid = kmalloc(sizeof(*uid) + n + 1, GFP_KERNEL);
+	if (!uid)
+		return -ENOMEM;
+	uid->len = n;
+
+	memcpy(uid->name, datap, n);
+	uid->name[n] = 0;
+
+	rc = uidfnx(uid, fnxdata);
+	if (rc == 0)
+		return rc; /* uidfnx keeps the record */
+	if (rc == 1)
+		rc = 0;
+
+	ksign_free_user_id(uid);
+	return rc;
+} /* end ksign_parse_user_id() */
+
+/*****************************************************************************/
+/*
+ * extract a public key embedded in a signature
+ */
+static int ksign_parse_key(const uint8_t *datap, const uint8_t *endp,
+			   uint8_t *hdr, int hdrlen,
+			   ksign_public_key_actor_t pkfnx, void *fnxdata)
+{
+	struct ksign_public_key *pk;
+	struct crypto_tfm *sha1_tfm;
+	unsigned long timestamp, expiredate;
+	uint8_t sha1[SHA1_DIGEST_SIZE];
+	int i, version;
+	int is_v4 = 0;
+	int rc = 0;
+
+	if (endp - datap < 12) {
+		printk("ksign: public key packet too short\n");
+		return -EBADMSG;
+	}
+
+	version = *datap++;
+	switch (version) {
+	case 4:
+		is_v4 = 1;
+	case 2:
+	case 3:
+		break;
+	default:
+		printk("ksign: public key packet with unknown version %d\n",
+		       version);
+		return -EBADMSG;
+	}
+
+	timestamp = read_32(&datap);
+	if (is_v4)
+		expiredate = 0; /* have to get it from the selfsignature */
+	else {
+		unsigned short ndays;
+		ndays = read_16(&datap);
+		if (ndays)
+			expiredate = timestamp + ndays * 86400L;
+		else
+			expiredate = 0;
+	}
+
+	if (*datap++ != PUBKEY_ALGO_DSA) {
+		printk("ksign: public key packet with unknown version %d\n",
+		       version);
+		return 0;
+	}
+
+	/* extract the stuff from the DSA public key */
+	pk = kmalloc(sizeof(struct ksign_public_key), GFP_KERNEL);
+	if (!pk)
+		return -ENOMEM;
+
+	memset(pk, 0, sizeof(struct ksign_public_key));
+	atomic_set(&pk->count, 1);
+	pk->timestamp	= timestamp;
+	pk->expiredate	= expiredate;
+	pk->hdrbytes	= hdrlen;
+	pk->version	= version;
+
+	for (i = 0; i < DSA_NPKEY; i++) {
+		unsigned int remaining = endp - datap;
+		pk->pkey[i] = mpi_read_from_buffer(datap, &remaining);
+		datap += remaining;
+	}
+
+	rc = -ENOMEM;
+
+	sha1_tfm = crypto_alloc_tfm2("sha1", 0, 1);
+	if (!sha1_tfm)
+		goto cleanup;
+
+	ksign_calc_pk_keyid(sha1_tfm, pk);
+	crypto_digest_final(sha1_tfm, sha1);
+	crypto_free_tfm(sha1_tfm);
+
+	pk->keyid[0] = sha1[12] << 24 | sha1[13] << 16 | sha1[14] << 8 | sha1[15];
+	pk->keyid[1] = sha1[16] << 24 | sha1[17] << 16 | sha1[18] << 8 | sha1[19];
+
+	rc = 0;
+	if (pkfnx)
+		rc = pkfnx(pk, fnxdata);
+
+ cleanup:
+	ksign_put_public_key(pk);
+	return rc;
+} /* end ksign_parse_key() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static const uint8_t *ksign_find_sig_issuer(const uint8_t *buffer)
+{
+	size_t buflen;
+	size_t n;
+	int type;
+	int seq = 0;
+
+	if (!buffer)
+		return NULL;
+
+	buflen = read_16(&buffer);
+	while (buflen) {
+		n = *buffer++; buflen--;
+		if (n == 255) {
+			if (buflen < 4)
+				goto too_short;
+			n = read_32(&buffer);
+			buflen -= 4;
+		}
+		else if (n >= 192) {
+			if(buflen < 2)
+				goto too_short;
+			n = ((n - 192) << 8) + *buffer + 192;
+			buffer++;
+			buflen--;
+		}
+
+		if (buflen < n)
+			goto too_short;
+
+		type = *buffer & 0x7f;
+		if (!(++seq > 0))
+			;
+		else if (type == SIGSUBPKT_ISSUER) { /* found */
+			buffer++;
+			n--;
+			if (n > buflen || n < 8)
+				goto too_short;
+			return buffer;
+		}
+
+		buffer += n;
+		buflen -= n;
+	}
+
+ too_short:
+	return NULL; /* end of subpackets; not found */
+} /* end ksign_find_sig_issuer() */
+
+/*****************************************************************************/
+/*
+ * extract signature data embedded in a signature
+ */
+static int ksign_parse_signature(const uint8_t *datap, const uint8_t *endp,
+				 ksign_signature_actor_t sigfnx, void *fnxdata)
+{
+	struct ksign_signature *sig;
+	size_t n;
+	int version, is_v4 = 0;
+	int rc;
+	int i;
+
+	if (endp - datap < 16) {
+		printk("ksign: signature packet too short\n");
+		return -EBADMSG;
+	}
+
+	version = *datap++;
+	switch (version) {
+	case 4:
+		is_v4 = 1;
+	case 3:
+	case 2:
+		break;
+	default:
+		printk("ksign: signature packet with unknown version %d\n", version);
+		return 0;
+	}
+
+	/* store information */
+	sig = kmalloc(sizeof(*sig), GFP_KERNEL);
+	if (!sig)
+		return -ENOMEM;
+
+	memset(sig, 0, sizeof(*sig));
+	sig->version = version;
+
+	if (!is_v4)
+		datap++; /* ignore md5 length */
+
+	sig->sig_class = *datap++;
+	if (!is_v4) {
+		sig->timestamp = read_32(&datap);
+		sig->keyid[0] = read_32(&datap);
+		sig->keyid[1] = read_32(&datap);
+	}
+
+	rc = 0;
+	if (*datap++ != PUBKEY_ALGO_DSA) {
+		printk("ksign: ignoring non-DSA signature\n");
+		goto leave;
+	}
+	if (*datap++ != DIGEST_ALGO_SHA1) {
+		printk("ksign: ignoring non-SHA1 signature\n");
+		goto leave;
+	}
+
+	rc = -EBADMSG;
+	if (is_v4) { /* read subpackets */
+		n = read_16(&datap); /* length of hashed data */
+		if (n > 10000) {
+			printk("ksign: signature packet: hashed data too long\n");
+			goto leave;
+		}
+		if (n) {
+			if ((size_t)(endp - datap) < n) {
+				printk("ksign: signature packet: available data too short\n");
+				goto leave;
+			}
+			sig->hashed_data = kmalloc(n + 2, GFP_KERNEL);
+			if (!sig->hashed_data) {
+				rc = -ENOMEM;
+				goto leave;
+			}
+			sig->hashed_data[0] = n >> 8;
+			sig->hashed_data[1] = n;
+			memcpy(sig->hashed_data + 2, datap, n);
+			datap += n;
+		}
+
+		n = read_16(&datap); /* length of unhashed data */
+		if (n > 10000) {
+			printk("ksign: signature packet: unhashed data too long\n");
+			goto leave;
+		}
+		if (n) {
+			if ((size_t) (endp - datap) < n) {
+				printk("ksign: signature packet: available data too short\n");
+				goto leave;
+			}
+			sig->unhashed_data = kmalloc(n + 2, GFP_KERNEL);
+			if (!sig->unhashed_data) {
+				rc = -ENOMEM;
+				goto leave;
+			}
+			sig->unhashed_data[0] = n >> 8;
+			sig->unhashed_data[1] = n;
+			memcpy(sig->unhashed_data + 2, datap, n);
+			datap += n;
+		}
+	}
+
+	if (endp - datap < 5) { /* sanity check */
+		printk("ksign: signature packet too short\n");
+		goto leave;
+	}
+
+	sig->digest_start[0] = *datap++;
+	sig->digest_start[1] = *datap++;
+
+	if (is_v4) {
+		const uint8_t *p;
+
+		p = ksign_find_sig_issuer(sig->hashed_data);
+		if (!p)
+			p = ksign_find_sig_issuer(sig->unhashed_data);
+		if (!p)
+			printk("ksign: signature packet without issuer\n");
+		else {
+			sig->keyid[0] = buffer_to_u32(p);
+			sig->keyid[1] = buffer_to_u32(p + 4);
+		}
+	}
+
+	for (i = 0; i < DSA_NSIG; i++) {
+		unsigned remaining = endp - datap;
+		sig->data[i] = mpi_read_from_buffer(datap, &remaining);
+		datap += remaining;
+	}
+
+	rc = 0;
+	if (sigfnx) {
+		rc = sigfnx(sig, fnxdata);
+		if (rc == 0)
+			return rc; /* sigfnx keeps the signature */
+		if (rc == 1)
+			rc = 0;
+	}
+
+ leave:
+	ksign_free_signature(sig);
+	return rc;
+} /* end ksign_parse_signature() */
+
+/*****************************************************************************/
+/*
+ * parse the next packet and call appropriate handler function for known types
+ * - returns:
+ *     0 on EOF
+ *     1 if there might be more packets
+ *     -EBADMSG if the packet is in an invalid format
+ *     -ve on other error
+ */
+static int ksign_parse_one_packet(const uint8_t **datap,
+				  const uint8_t *endp,
+				  ksign_signature_actor_t sigfnx,
+				  ksign_public_key_actor_t pkfnx,
+				  ksign_user_id_actor_t uidfnx,
+				  void *data)
+{
+	int rc, c, ctb, pkttype, lenuint8_ts;
+	unsigned long pktlen;
+	uint8_t hdr[8];
+	int hdrlen;
+
+	/* extract the next packet and dispatch it */
+	rc = 0;
+	if (*datap >= endp)
+		goto leave;
+	ctb = *(*datap)++;
+
+	rc = -EBADMSG;
+
+	hdrlen = 0;
+	hdr[hdrlen++] = ctb;
+	if (!(ctb & 0x80)) {
+		printk("ksign: invalid packet (ctb=%02x)\n", ctb);
+		goto leave;
+	}
+
+	pktlen = 0;
+	if (ctb & 0x40) {
+		pkttype = ctb & 0x3f;
+		if (*datap >= endp) {
+			printk("ksign: 1st length byte missing\n");
+			goto leave;
+		}
+		c = *(*datap)++;
+		hdr[hdrlen++] = c;
+
+		if (c < 192) {
+			pktlen = c;
+		}
+		else if (c < 224) {
+			pktlen = (c - 192) * 256;
+			if (*datap >= endp) {
+				printk("ksign: 2nd length uint8_t missing\n");
+				goto leave;
+			}
+			c = *(*datap)++;
+			hdr[hdrlen++] = c;
+			pktlen += c + 192;
+		}
+		else if (c == 255) {
+			if (*datap + 3 >= endp) {
+				printk("ksign: 4 uint8_t length invalid\n");
+				goto leave;
+			}
+			pktlen  = (hdr[hdrlen++] = *(*datap)++ << 24	);
+			pktlen |= (hdr[hdrlen++] = *(*datap)++ << 16	);
+			pktlen |= (hdr[hdrlen++] = *(*datap)++ <<  8	);
+			pktlen |= (hdr[hdrlen++] = *(*datap)++ <<  0	);
+		}
+		else {
+			pktlen = 0;/* to indicate partial length */
+		}
+	}
+	else {
+		pkttype = (ctb >> 2) & 0xf;
+		lenuint8_ts = ((ctb & 3) == 3) ? 0 : (1 << (ctb & 3));
+		if( !lenuint8_ts ) {
+			pktlen = 0; /* don't know the value */
+		}
+		else {
+			if (*datap + lenuint8_ts > endp) {
+				printk("ksign: length uint8_ts missing\n");
+				goto leave;
+			}
+			for( ; lenuint8_ts; lenuint8_ts-- ) {
+				pktlen <<= 8;
+				pktlen |= hdr[hdrlen++] = *(*datap)++;
+			}
+		}
+	}
+
+	if (*datap + pktlen > endp) {
+		printk("ksign: packet length longer than available data\n");
+		goto leave;
+	}
+
+	/* deal with the next packet appropriately */
+	switch (pkttype) {
+	case PKT_PUBLIC_KEY:
+		rc = ksign_parse_key(*datap, *datap + pktlen, hdr, hdrlen, pkfnx, data);
+		break;
+	case PKT_SIGNATURE:
+		rc = ksign_parse_signature(*datap, *datap + pktlen, sigfnx, data);
+		break;
+	case PKT_USER_ID:
+		rc = ksign_parse_user_id(*datap, *datap + pktlen, uidfnx, data);
+		break;
+	default:
+		rc = 0; /* unknown packet */
+		break;
+	}
+
+	*datap += pktlen;
+ leave:
+	return rc;
+} /* end ksign_parse_one_packet() */
+
+/*****************************************************************************/
+/*
+ * parse the contents of a packet buffer, passing the signature, public key and
+ * user ID to the caller's callback functions
+ */
+int ksign_parse_packets(const uint8_t *buf,
+			size_t size,
+			ksign_signature_actor_t sigfnx,
+			ksign_public_key_actor_t pkfnx,
+			ksign_user_id_actor_t uidfnx,
+			void *data)
+{
+	const uint8_t *datap, *endp;
+	int rc;
+
+	datap = buf;
+	endp = buf + size;
+	do {
+		rc = ksign_parse_one_packet(&datap, endp,
+					    sigfnx, pkfnx, uidfnx, data);
+	} while (rc == 0 && datap < endp);
+
+	return rc;
+} /* end ksign_parse_packets() */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-publickey.c linux-902/crypto/signature/ksign-publickey.c
--- linux-901/crypto/signature/ksign-publickey.c
+++ linux-902/crypto/signature/ksign-publickey.c
@@ -0,0 +1,19 @@
+#include "local.h"
+
+#include "key.h"
+
+static int __init ksign_init(void)
+{
+	int rc;
+
+	printk("ksign: Installing public key data\n");
+
+	rc = ksign_load_keyring_from_buffer(ksign_def_public_key,
+					    ksign_def_public_key_size);
+	if (rc < 0)
+		printk("Unable to load default keyring: error=%d\n", -rc);
+
+	return rc;
+}
+
+module_init(ksign_init)
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/local.h linux-902/crypto/signature/local.h
--- linux-901/crypto/signature/local.h
+++ linux-902/crypto/signature/local.h
@@ -0,0 +1,163 @@
+/* local.h: kernel signature checker internal defs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ * - Derived from GnuPG packet.h - packet definitions
+ *   - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <linux/list.h>
+#include <linux/crypto.h>
+#include <linux/crypto/ksign.h>
+#include <linux/crypto/mpi.h>
+#include <asm/atomic.h>
+
+#define SHA1_DIGEST_SIZE	20
+
+#define PUBKEY_USAGE_SIG	1	    /* key is good for signatures */
+#define PUBKEY_USAGE_ENC	2	    /* key is good for encryption */
+
+#define PUBKEY_ALGO_DSA		17
+#define DSA_NPKEY		4	/* number of MPI's in DSA public key */
+#define DSA_NSIG		2	/* number of MPI's in DSA signature */
+
+#define DIGEST_ALGO_SHA1	2
+
+typedef enum {
+	PKT_NONE			= 0,
+	PKT_SIGNATURE			= 2,	/* secret key encrypted packet */
+	PKT_PUBLIC_KEY			= 6,	/* public key */
+	PKT_USER_ID			= 13,	/* user id packet */
+} pkttype_t;
+
+typedef enum {
+	SIGSUBPKT_TEST_CRITICAL		= -3,
+	SIGSUBPKT_NONE			= 0,
+	SIGSUBPKT_SIG_CREATED		= 2,	/* signature creation time */
+	SIGSUBPKT_SIG_EXPIRE		= 3,	/* signature expiration time */
+	SIGSUBPKT_EXPORTABLE		= 4,	/* exportable */
+	SIGSUBPKT_TRUST			= 5,	/* trust signature */
+	SIGSUBPKT_REGEXP		= 6,	/* regular expression */
+	SIGSUBPKT_REVOCABLE		= 7,	/* revocable */
+	SIGSUBPKT_KEY_EXPIRE		= 9,	/* key expiration time */
+	SIGSUBPKT_ARR			= 10,	/* additional recipient request */
+	SIGSUBPKT_PREF_SYM		= 11,	/* preferred symmetric algorithms */
+	SIGSUBPKT_REV_KEY		= 12,	/* revocation key */
+	SIGSUBPKT_ISSUER		= 16,	/* issuer key ID */
+	SIGSUBPKT_NOTATION		= 20,	/* notation data */
+	SIGSUBPKT_PREF_HASH		= 21,	/* preferred hash algorithms */
+	SIGSUBPKT_PREF_COMPR		= 22,	/* preferred compression algorithms */
+	SIGSUBPKT_KS_FLAGS		= 23,	/* key server preferences */
+	SIGSUBPKT_PREF_KS		= 24,	/* preferred key server */
+	SIGSUBPKT_PRIMARY_UID		= 25,	/* primary user id */
+	SIGSUBPKT_POLICY		= 26,	/* policy URL */
+	SIGSUBPKT_KEY_FLAGS		= 27,	/* key flags */
+	SIGSUBPKT_SIGNERS_UID		= 28,	/* signer's user id */
+	SIGSUBPKT_REVOC_REASON		= 29,	/* reason for revocation */
+	SIGSUBPKT_PRIV_VERIFY_CACHE	= 101,	/* cache verification result */
+
+	SIGSUBPKT_FLAG_CRITICAL		= 128
+} sigsubpkttype_t;
+
+/*
+ * signature record
+ */
+struct ksign_signature
+{
+	uint32_t	keyid[2];		/* 64 bit keyid */
+	time_t		timestamp;		/* signature made */
+	uint8_t		version;
+	uint8_t		sig_class;		/* sig classification, append for MD calculation*/
+	uint8_t		*hashed_data;		/* all subpackets with hashed  data (v4 only) */
+	uint8_t		*unhashed_data;		/* ditto for unhashed data */
+	uint8_t		digest_start[2];	/* first 2 uint8_ts of the digest */
+	MPI		data[DSA_NSIG];
+};
+
+extern void ksign_free_signature(struct ksign_signature *sig);
+
+/*
+ * public key record
+ */
+struct ksign_public_key
+{
+	struct list_head link;
+	atomic_t	count;			/* ref count */
+	time_t		timestamp;		/* key made */
+	time_t		expiredate;		/* expires at this date or 0 if not at all */
+	uint8_t		hdrbytes;		/* number of header bytes */
+	uint8_t		version;
+	int		is_valid;		/* key (especially subkey) is valid */
+	unsigned long	local_id;		/* internal use, valid if > 0 */
+	uint32_t	main_keyid[2];		/* keyid of the primary key */
+	uint32_t	keyid[2];		/* calculated by keyid_from_pk() */
+	MPI		pkey[DSA_NPKEY];
+};
+
+extern void ksign_free_public_key(struct ksign_public_key *pk);
+
+static inline void ksign_put_public_key(struct ksign_public_key *pk)
+{
+	if (atomic_dec_and_test(&pk->count))
+		ksign_free_public_key(pk);
+}
+
+extern int ksign_load_keyring_from_buffer(const void *buffer, size_t size);
+
+extern struct ksign_public_key *ksign_get_public_key(const uint32_t *keyid);
+
+/*
+ * user ID record
+ */
+struct ksign_user_id
+{
+	int		len;			/* length of the name */
+	char		name[0];
+};
+
+extern void ksign_free_user_id(struct ksign_user_id *uid);
+
+/*
+ *
+ */
+typedef int (*ksign_signature_actor_t)(struct ksign_signature *, void *fnxdata);
+typedef int (*ksign_public_key_actor_t)(struct ksign_public_key *, void *fnxdata);
+typedef int (*ksign_user_id_actor_t)(struct ksign_user_id *, void *fnxdata);
+
+extern int ksign_parse_packets(const uint8_t *buf,
+			       size_t size,
+			       ksign_signature_actor_t sigfnx,
+			       ksign_public_key_actor_t pkfnx,
+			       ksign_user_id_actor_t uidfnx,
+			       void *data);
+
+extern int DSA_verify(const MPI datahash, const MPI sig[], const MPI pkey[]);
+
+/*
+ * fast access to the digest
+ * - we _know_ the data is locked into kernel memory, so we don't want to have
+ *   to kmap() it
+ */
+static inline void SHA1_putc(struct crypto_tfm *sha1, uint8_t ch)
+{
+	crypto_digest_update_kernel(sha1, &ch, 1);
+}
+
+static inline void SHA1_write(struct crypto_tfm *sha1, const void *s, size_t n)
+{
+	crypto_digest_update_kernel(sha1, s, n);
+}
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/Makefile linux-902/crypto/signature/Makefile
--- linux-901/crypto/signature/Makefile
+++ linux-902/crypto/signature/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the signature checker
+#
+
+obj-y := \
+	ksign.o \
+	ksign-parse.o \
+	ksign-keyring.o \
+	ksign-publickey.o \
+	dsa.o
diff -urNp --exclude-from=/home/davej/.exclude linux-901/include/linux/crypto/ksign.h linux-902/include/linux/crypto/ksign.h
--- linux-901/include/linux/crypto/ksign.h
+++ linux-902/include/linux/crypto/ksign.h
@@ -0,0 +1,22 @@
+/* ksign.h: in-kernel signature checker
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_CRYPTO_KSIGN_H
+#define _LINUX_CRYPTO_KSIGN_H
+
+#include <linux/types.h>
+
+#ifdef CONFIG_CRYPTO_SIGNATURE
+extern int ksign_verify_signature(const char *sig, unsigned sig_size,
+				  struct crypto_tfm *sha1);
+#endif
+
+#endif /* _LINUX_CRYPTO_KSIGN_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/include/linux/crypto.h linux-902/include/linux/crypto.h
--- linux-901/include/linux/crypto.h
+++ linux-902/include/linux/crypto.h
@@ -167,6 +167,8 @@ struct digest_tfm {
 	void (*dit_init)(struct crypto_tfm *tfm);
 	void (*dit_update)(struct crypto_tfm *tfm,
 	                   struct scatterlist *sg, unsigned int nsg);
+	void (*dit_update_kernel)(struct crypto_tfm *tfm,
+				  const void *data, size_t count);
 	void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
 	void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
 	                   unsigned int nsg, u8 *out);
@@ -287,6 +289,14 @@ static inline void crypto_digest_update(
 	tfm->crt_digest.dit_update(tfm, sg, nsg);
 }
 
+static inline void crypto_digest_update_kernel(struct crypto_tfm *tfm,
+					       const void *data,
+					       size_t count)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_update_kernel(tfm, data, count);
+}
+
 static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
 {
 	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
--- linux-2.6.14/crypto/signature/ksign-keyring.c~	2005-11-22 14:11:25.000000000 -0500
+++ linux-2.6.14/crypto/signature/ksign-keyring.c	2005-11-22 14:11:38.000000000 -0500
@@ -85,6 +85,8 @@ struct ksign_public_key *ksign_get_publi
 		}
 	}
 
+	pk = NULL;
+
  found:
 	up_read(&keyring_sem);
 

linux-2.6-modsign-mpilib.patch:
 crypto/mpi/Makefile               |   30 
 crypto/mpi/generic_mpi-asm-defs.h |   10 
 crypto/mpi/generic_mpih-add1.c    |   62 +
 crypto/mpi/generic_mpih-lshift.c  |   66 +
 crypto/mpi/generic_mpih-mul1.c    |   58 +
 crypto/mpi/generic_mpih-mul2.c    |   63 +
 crypto/mpi/generic_mpih-mul3.c    |   64 +
 crypto/mpi/generic_mpih-rshift.c  |   65 +
 crypto/mpi/generic_mpih-sub1.c    |   62 +
 crypto/mpi/generic_udiv-w-sdiv.c  |  130 +++
 crypto/mpi/longlong.h             | 1502 ++++++++++++++++++++++++++++++++++++++
 crypto/mpi/mpi-add.c              |  258 ++++++
 crypto/mpi/mpi-bit.c              |  245 ++++++
 crypto/mpi/mpi-cmp.c              |   71 +
 crypto/mpi/mpi-div.c              |  345 ++++++++
 crypto/mpi/mpi-gcd.c              |   60 +
 crypto/mpi/mpi-inline.c           |   33 
 crypto/mpi/mpi-inline.h           |  128 +++
 crypto/mpi/mpi-internal.h         |  265 ++++++
 crypto/mpi/mpi-inv.c              |  148 +++
 crypto/mpi/mpi-mpow.c             |  113 ++
 crypto/mpi/mpi-mul.c              |  202 +++++
 crypto/mpi/mpi-pow.c              |  312 +++++++
 crypto/mpi/mpi-scan.c             |  129 +++
 crypto/mpi/mpicoder.c             |  359 +++++++++
 crypto/mpi/mpih-cmp.c             |   58 +
 crypto/mpi/mpih-div.c             |  534 +++++++++++++
 crypto/mpi/mpih-mul.c             |  547 +++++++++++++
 crypto/mpi/mpiutil.c              |  214 +++++
 include/linux/crypto/mpi.h        |  147 +++
 30 files changed, 6280 insertions(+)

--- NEW FILE linux-2.6-modsign-mpilib.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpi-asm-defs.h linux-903/crypto/mpi/generic_mpi-asm-defs.h
--- linux-902/crypto/mpi/generic_mpi-asm-defs.h
+++ linux-903/crypto/mpi/generic_mpi-asm-defs.h
@@ -0,0 +1,10 @@
+/* This file defines some basic constants for the MPI machinery.  We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here.  */
+#define BYTES_PER_MPI_LIMB  (SIZEOF_UNSIGNED_LONG)
+
+
+
+
+
+
diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-add1.c linux-903/crypto/mpi/generic_mpih-add1.c
--- linux-902/crypto/mpi/generic_mpih-add1.c
+++ linux-903/crypto/mpi/generic_mpih-add1.c
@@ -0,0 +1,62 @@
+/* mpihelp-add_1.c  -  MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 
+ *               2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ *	 Actually it's the same code with only minor changes in the
+ *	 way the data is stored; this is to support the abstraction
+ *	 of an optional secure memory allocation which may be used
+ *	 to avoid revealing of sensitive data due to paging etc.
+ *	 The GNU MP Library itself is published under the LGPL;
+ *	 however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+	       mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+    mpi_limb_t x, y, cy;
+    mpi_size_t j;
+
+    /* The loop counter and index J goes from -SIZE to -1.  This way
+       the loop becomes faster.  */
+    j = -size;
+
+    /* Offset the base pointers to compensate for the negative indices. */
+    s1_ptr -= j;
+    s2_ptr -= j;
+    res_ptr -= j;
+
+    cy = 0;
+    do {
+	y = s2_ptr[j];
+	x = s1_ptr[j];
+	y += cy;		  /* add previous carry to one addend */
+	cy = y < cy;		  /* get out carry from that addition */
+	y += x; 		  /* add other addend */
+	cy += y < x;		  /* get out carry from that add, combine */
+	res_ptr[j] = y;
+    } while( ++j );
+
+    return cy;
+}
+
diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-lshift.c linux-903/crypto/mpi/generic_mpih-lshift.c
--- linux-902/crypto/mpi/generic_mpih-lshift.c
+++ linux-903/crypto/mpi/generic_mpih-lshift.c
@@ -0,0 +1,66 @@
+/* mpihelp-lshift.c  -	MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ *	 Actually it's the same code with only minor changes in the
+ *	 way the data is stored; this is to support the abstraction
+ *	 of an optional secure memory allocation which may be used
+ *	 to avoid revealing of sensitive data due to paging etc.
+ *	 The GNU MP Library itself is published under the LGPL;
+ *	 however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
+ * and store the USIZE least significant digits of the result at WP.
+ * Return the bits shifted out from the most significant digit.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be >= UP.
+ */
+
+mpi_limb_t
+mpihelp_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+					    unsigned int cnt)
+{
+    mpi_limb_t high_limb, low_limb;
+    unsigned sh_1, sh_2;
+    mpi_size_t i;
+    mpi_limb_t retval;
+
+    sh_1 = cnt;
+    wp += 1;
+    sh_2 = BITS_PER_MPI_LIMB - sh_1;
+    i = usize - 1;
+    low_limb = up[i];
+    retval = low_limb >> sh_2;
+    high_limb = low_limb;
+    while( --i >= 0 ) {
+	low_limb = up[i];
+	wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+	high_limb = low_limb;
+    }
+    wp[i] = high_limb << sh_1;
+
+    return retval;
+}
+
+
diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-mul1.c linux-903/crypto/mpi/generic_mpih-mul1.c
--- linux-902/crypto/mpi/generic_mpih-mul1.c
+++ linux-903/crypto/mpi/generic_mpih-mul1.c
@@ -0,0 +1,58 @@
+/* mpihelp-mul_1.c  -  MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ *	 Actually it's the same code with only minor changes in the
+ *	 way the data is stored; this is to support the abstraction
+ *	 of an optional secure memory allocation which may be used
+ *	 to avoid revealing of sensitive data due to paging etc.
+ *	 The GNU MP Library itself is published under the LGPL;
+ *	 however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+						    mpi_limb_t s2_limb)
+{
+    mpi_limb_t cy_limb;
+    mpi_size_t j;
+    mpi_limb_t prod_high, prod_low;
+
+    /* The loop counter and index J goes from -S1_SIZE to -1.  This way
+     * the loop becomes faster.  */
+    j = -s1_size;
+
+    /* Offset the base pointers to compensate for the negative indices.  */
+    s1_ptr -= j;
[...6001 lines suppressed...]
+	mpi_ptr_t wp, up;
+	mpi_size_t usize = u->nlimbs;
+	int usign = u->sign;
+
+	if (RESIZE_IF_NEEDED(w, (size_t) usize) < 0)
+		return -ENOMEM;
+
+	wp = w->d;
+	up = u->d;
+	MPN_COPY(wp, up, usize);
+	w->nlimbs = usize;
+	w->nbits = u->nbits;
+	w->flags = u->flags;
+	w->sign = usign;
+	return 0;
+}
+
+
+int mpi_set_ui(MPI w, unsigned long u)
+{
+	if (RESIZE_IF_NEEDED(w, 1) < 0)
+		return -ENOMEM;
+	w->d[0] = u;
+	w->nlimbs = u? 1:0;
+	w->sign = 0;
+	w->nbits = 0;
+	w->flags = 0;
+	return 0;
+}
+
+MPI mpi_alloc_set_ui(unsigned long u)
+{
+	MPI w = mpi_alloc(1);
+	if (!w)
+		return w;
+	w->d[0] = u;
+	w->nlimbs = u? 1:0;
+	w->sign = 0;
+	return w;
+}
+
+
+void mpi_swap(MPI a, MPI b)
+{
+	struct gcry_mpi tmp;
+
+	tmp = *a; *a = *b; *b = tmp;
+}
+
diff -urNp --exclude-from=/home/davej/.exclude linux-902/include/linux/crypto/mpi.h linux-903/include/linux/crypto/mpi.h
--- linux-902/include/linux/crypto/mpi.h
+++ linux-903/include/linux/crypto/mpi.h
@@ -0,0 +1,147 @@
+/* mpi.h  -  Multi Precision Integers
+ *	Copyright (C) 1994, 1996, 1998, 1999,
+ *                    2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ *	 Actually it's the same code with only minor changes in the
+ *	 way the data is stored; this is to support the abstraction
+ *	 of an optional secure memory allocation which may be used
+ *	 to avoid revealing of sensitive data due to paging etc.
+ *	 The GNU MP Library itself is published under the LGPL;
+ *	 however I decided to publish this code under the plain GPL.
+ */
+
+#ifndef G10_MPI_H
+#define G10_MPI_H
+
+#include <linux/types.h>
+
+/* DSI defines */
+
+#define SHA1_DIGEST_LENGTH   20
+
+/*end of DSI defines */
+
+#define BYTES_PER_MPI_LIMB	(BITS_PER_LONG / 8)
+#define BITS_PER_MPI_LIMB	BITS_PER_LONG
+
+typedef unsigned long int mpi_limb_t;
+typedef   signed long int mpi_limb_signed_t;
+
+struct gcry_mpi {
+	int	alloced;    /* array size (# of allocated limbs) */
+	int	nlimbs;     /* number of valid limbs */
+	int	nbits;	    /* the real number of valid bits (info only) */
+	int	sign;	    /* indicates a negative number */
+	unsigned flags; /* bit 0: array must be allocated in secure memory space */
+	/* bit 1: not used */
+	/* bit 2: the limb is a pointer to some m_alloced data */
+	mpi_limb_t *d;  /* array with the limbs */
+};
+
+typedef struct gcry_mpi *MPI;
+
+#define MPI_NULL NULL
+
+#define mpi_get_nlimbs(a)     ((a)->nlimbs)
+#define mpi_is_neg(a)	      ((a)->sign)
+
+/*-- mpiutil.c --*/
+MPI mpi_alloc( unsigned nlimbs );
+MPI mpi_alloc_secure( unsigned nlimbs );
+MPI mpi_alloc_like( MPI a );
+void mpi_free( MPI a );
+int mpi_resize( MPI a, unsigned nlimbs );
+int  mpi_copy( MPI *copy, const MPI a );
+void mpi_clear( MPI a );
+int mpi_set( MPI w, MPI u);
+int mpi_set_ui( MPI w, ulong u);
+MPI  mpi_alloc_set_ui( unsigned long u);
+void mpi_m_check( MPI a );
+void mpi_swap( MPI a, MPI b);
+
+/*-- mpicoder.c --*/
+MPI do_encode_md(const void *sha_buffer, unsigned nbits);
+MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
+int mpi_fromstr(MPI val, const char *str);
+u32 mpi_get_keyid( MPI a, u32 *keyid );
+void *mpi_get_buffer( MPI a, unsigned *nbytes, int *sign );
+void *mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign );
+int  mpi_set_buffer( MPI a, const void *buffer, unsigned nbytes, int sign );
+
+#define log_mpidump g10_log_mpidump
+
+/*-- mpi-add.c --*/
+int mpi_add_ui(MPI w, MPI u, ulong v );
+int mpi_add(MPI w, MPI u, MPI v);
+int mpi_addm(MPI w, MPI u, MPI v, MPI m);
+int mpi_sub_ui(MPI w, MPI u, ulong v );
+int mpi_sub( MPI w, MPI u, MPI v);
+int mpi_subm( MPI w, MPI u, MPI v, MPI m);
+
+/*-- mpi-mul.c --*/
+int mpi_mul_ui(MPI w, MPI u, ulong v );
+int mpi_mul_2exp( MPI w, MPI u, ulong cnt);
+int mpi_mul( MPI w, MPI u, MPI v);
+int mpi_mulm( MPI w, MPI u, MPI v, MPI m);
+
+/*-- mpi-div.c --*/
+ulong mpi_fdiv_r_ui( MPI rem, MPI dividend, ulong divisor );
+int mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor );
+int mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor );
+int mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor );
+int mpi_tdiv_r( MPI rem, MPI num, MPI den);
+int mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den);
+int mpi_tdiv_q_2exp( MPI w, MPI u, unsigned count );
+int   mpi_divisible_ui(const MPI dividend, ulong divisor );
+
+/*-- mpi-gcd.c --*/
+int mpi_gcd( MPI g, const MPI a, const MPI b );
+
+/*-- mpi-pow.c --*/
+int mpi_pow( MPI w, MPI u, MPI v);
+int mpi_powm( MPI res, MPI base, MPI exp, MPI mod);
+
+/*-- mpi-mpow.c --*/
+int mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
+
+/*-- mpi-cmp.c --*/
+int mpi_cmp_ui( MPI u, ulong v );
+int mpi_cmp( MPI u, MPI v );
+
+/*-- mpi-scan.c --*/
+int mpi_getbyte( MPI a, unsigned idx );
+void mpi_putbyte( MPI a, unsigned idx, int value );
+unsigned mpi_trailing_zeros( MPI a );
+
+/*-- mpi-bit.c --*/
+void mpi_normalize( MPI a );
+unsigned mpi_get_nbits( MPI a );
+int  mpi_test_bit( MPI a, unsigned n );
+int mpi_set_bit( MPI a, unsigned n );
+int mpi_set_highbit( MPI a, unsigned n );
+void mpi_clear_highbit( MPI a, unsigned n );
+void mpi_clear_bit( MPI a, unsigned n );
+int mpi_rshift( MPI x, MPI a, unsigned n );
+
+/*-- mpi-inv.c --*/
+int mpi_invm( MPI x, MPI u, MPI v );
+
+
+#endif /*G10_MPI_H*/

linux-2.6-modsign-script.patch:
 Makefile      |   27 +
 mod-extract.c |  900 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 modsign.sh    |   57 +++
 3 files changed, 984 insertions(+)

--- NEW FILE linux-2.6-modsign-script.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/Makefile linux-904/scripts/modsign/Makefile
--- linux-903/scripts/modsign/Makefile
+++ linux-904/scripts/modsign/Makefile
@@ -0,0 +1,27 @@
+# Set the following to `true' to make a debuggable build.
+# Leave this set to `false' for production use.
+DEBUG = true
+
+
+ROOT =		mod-extract
+VERSION =	0.1
+INSTALL_DIR =	/usr/local/bin
+RELEASE_NAME =	$(ROOT)-$(VERSION)
+
+CC = gcc
+
+INCLUDES = 
+CFLAGS = -g -O -Wall
+
+OBJS =	mod-extract.o
+
+all: $(ROOT)
+
+$(ROOT): $(OBJS)
+	$(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) -lbfd -liberty $(LIB_OBJS) $(ARCH_LIB_OBJS)
+
+.c.o:
+	$(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@
+
+clean:
+	-rm $(OBJS) $(ROOT)
diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/mod-extract.c linux-904/scripts/modsign/mod-extract.c
--- linux-903/scripts/modsign/mod-extract.c
+++ linux-904/scripts/modsign/mod-extract.c
@@ -0,0 +1,900 @@
+/* mod-extract.c: module extractor for signing
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <elf.h>
+#include <asm/byteorder.h>
+
+void extract_elf64(void *buffer, size_t size, Elf64_Ehdr *hdr);
+void extract_elf32(void *buffer, size_t size, Elf32_Ehdr *hdr);
+
+struct byteorder {
+	uint16_t (*get16)(const uint16_t *);
+	uint32_t (*get32)(const uint32_t *);
+	uint64_t (*get64)(const uint64_t *);
+	void (*set16)(uint16_t *, uint16_t);
+	void (*set32)(uint32_t *, uint32_t);
+	void (*set64)(uint64_t *, uint64_t);
+};
+
+uint16_t get16_le(const uint16_t *p) { return __le16_to_cpu(*p); }
+uint32_t get32_le(const uint32_t *p) { return __le32_to_cpu(*p); }
+uint64_t get64_le(const uint64_t *p) { return __le64_to_cpu(*p); }
+uint16_t get16_be(const uint16_t *p) { return __be16_to_cpu(*p); }
+uint32_t get32_be(const uint32_t *p) { return __be32_to_cpu(*p); }
+uint64_t get64_be(const uint64_t *p) { return __be64_to_cpu(*p); }
+
+void set16_le(uint16_t *p, uint16_t n) { *p = __cpu_to_le16(n); }
+void set32_le(uint32_t *p, uint32_t n) { *p = __cpu_to_le32(n); }
+void set64_le(uint64_t *p, uint64_t n) { *p = __cpu_to_le64(n); }
+void set16_be(uint16_t *p, uint16_t n) { *p = __cpu_to_be16(n); }
+void set32_be(uint32_t *p, uint32_t n) { *p = __cpu_to_be32(n); }
+void set64_be(uint64_t *p, uint64_t n) { *p = __cpu_to_be64(n); }
+
+const struct byteorder byteorder_le = {
+	get16_le, get32_le, get64_le,
+	set16_le, set32_le, set64_le
+};
+const struct byteorder byteorder_be = {
+	get16_be, get32_be, get64_be,
+	set16_be, set32_be, set64_be
+};
+const struct byteorder *order;
+
+uint16_t get16(const uint16_t *p) { return order->get16(p); }
+uint32_t get32(const uint32_t *p) { return order->get32(p); }
+uint64_t get64(const uint64_t *p) { return order->get64(p); }
+void set16(uint16_t *p, uint16_t n) { order->set16(p, n); }
+void set32(uint32_t *p, uint32_t n) { order->set32(p, n); }
+void set64(uint64_t *p, uint64_t n) { order->set64(p, n); }
+
+FILE *outfd;
+uint8_t csum, xcsum;
+
+void write_out(const void *data, size_t size)
+{
+	const uint8_t *p = data;
+	size_t loop;
+
+	for (loop = 0; loop < size; loop++) {
+		csum += p[loop];
+		xcsum += p[loop];
+	}
+
+	if (fwrite(data, 1, size, outfd) != size) {
+		perror("write");
+		exit(1);
+	}
+}
+
+#define write_out_val(VAL) write_out(&(VAL), sizeof(VAL))
+
+int is_verbose;
+
+void verbose(const char *fmt, ...) __attribute__((format(printf,1,2)));
+void verbose(const char *fmt, ...)
+{
+	va_list va;
+
+	if (is_verbose) {
+		va_start(va, fmt);
+		vprintf(fmt, va);
+		va_end(va);
+	}
+}
+
+void usage(void) __attribute__((noreturn));
+void usage(void)
+{
+	fprintf(stderr, "Usage: mod-extract [-v] <modulefile> <extractfile>\n");
+	exit(2);
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+int main(int argc, char **argv)
+{
+	struct stat st;
+	Elf32_Ehdr *hdr32;
+	Elf64_Ehdr *hdr64;
+	size_t len;
+	void *buffer;
+	int fd, be, b64;
+
+	while (argc > 1 && strcmp("-v", argv[1]) == 0) {
+		argv++;
+		argc--;
+		is_verbose++;
+	}
+
+	if (argc != 3)
+		usage();
+
+	/* map the module into memory */
+	fd = open(argv[1], O_RDONLY);
+	if (fd < 0) {
+		perror("open input");
+		exit(1);
+	}
+
+	if (fstat(fd, &st) < 0) {
+		perror("fstat");
+		exit(1);
+	}
+
+	len = st.st_size;
+
+	buffer = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+	if (buffer == MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+
+	if (close(fd) < 0) {
+		perror("close input");
+		exit(1);
+	}
+
+	/* check it's an ELF object */
+	hdr32 = buffer;
+	hdr64 = buffer;
+
+	if (hdr32->e_ident[EI_MAG0] != ELFMAG0 ||
+	    hdr32->e_ident[EI_MAG1] != ELFMAG1 ||
+	    hdr32->e_ident[EI_MAG2] != ELFMAG2 ||
+	    hdr32->e_ident[EI_MAG3] != ELFMAG3
+	    ) {
+		fprintf(stderr, "Module does not appear to be ELF\n");
+		exit(3);
+	}
+
+	/* determine endianness and word size */
+	b64 = (hdr32->e_ident[EI_CLASS] == ELFCLASS64);
+	be = (hdr32->e_ident[EI_DATA] == ELFDATA2MSB);
+	order = be ? &byteorder_be : &byteorder_le;
+
+	verbose("Module is %s-bit %s-endian\n",
+		b64 ? "64" : "32",
+		be ? "big" : "little");
+
+	/* open the output file */
+	outfd = fopen(argv[2], "w");
+	if (!outfd) {
+		perror("open output");
+		exit(1);
+	}
+
+	/* perform the extraction */
+	if (b64)
+ 		extract_elf64(buffer, len, hdr64);
+	else
+ 		extract_elf32(buffer, len, hdr32);
+
+	/* done */
+	if (fclose(outfd) == EOF) {
+		perror("close output");
+		exit(1);
+	}
+
+	return 0;
+
+} /* end main() */
+
+/*****************************************************************************/
+/*
+ * extract a RELA table
+ * - need to canonicalise the entries in case section addition/removal has
+ *   rearranged the symbol table and the section table
+ */
+void extract_elf64_rela(const void *buffer, int secix, int targetix,
+			const Elf64_Rela *relatab, size_t nrels,
+			const Elf64_Sym *symbols, size_t nsyms,
+			const Elf64_Shdr *sections, size_t nsects, int *canonmap,
+			const char *strings, size_t nstrings,
+			const char *sh_name)
+{
+	struct {
+		uint64_t	r_offset;
+		uint64_t	r_addend;
+		uint64_t	st_value;
+		uint64_t	st_size;
+		uint32_t	r_type;
+		uint16_t	st_shndx;
+		uint8_t		st_info;
+		uint8_t		st_other;
+
+	} __attribute__((packed)) relocation;
+
+	const Elf64_Sym *symbol;
+	size_t loop;
+
+	/* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+	for (loop = 0; loop < nrels; loop++) {
+		Elf64_Section st_shndx;
+		Elf64_Xword r_info;
+
+		/* decode the relocation */
+		r_info = get64(&relatab[loop].r_info);
+		relocation.r_offset = relatab[loop].r_offset;
+		relocation.r_addend = relatab[loop].r_addend;
+		set32(&relocation.r_type, ELF64_R_TYPE(r_info));
+
+		if (ELF64_R_SYM(r_info) >= nsyms) {
+			fprintf(stderr, "Invalid symbol ID %lx in relocation %zu\n",
+				ELF64_R_SYM(r_info), loop);
+			exit(1);
+		}
+
+		/* decode the symbol referenced by the relocation */
+		symbol = &symbols[ELF64_R_SYM(r_info)];
+		relocation.st_info = symbol->st_info;
+		relocation.st_other = symbol->st_other;
+		relocation.st_value = symbol->st_value;
+		relocation.st_size = symbol->st_size;
+		relocation.st_shndx = symbol->st_shndx;
+		st_shndx = get16(&symbol->st_shndx);
+
+		/* canonicalise the section used by the symbol */
+		if (st_shndx > SHN_UNDEF && st_shndx < nsects)
+			set16(&relocation.st_shndx, canonmap[st_shndx]);
+
+		write_out_val(relocation);
+
+		/* undefined symbols must be named if referenced */
+		if (st_shndx == SHN_UNDEF) {
+			const char *name = strings + get32(&symbol->st_name);
+			write_out(name, strlen(name) + 1);
+		}
+	}
+
+	verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
+
+} /* end extract_elf64_rela() */
+
+/*****************************************************************************/
+/*
+ * extract a REL table
+ * - need to canonicalise the entries in case section addition/removal has
+ *   rearranged the symbol table and the section table
+ */
+void extract_elf64_rel(const void *buffer, int secix, int targetix,
+		       const Elf64_Rel *relatab, size_t nrels,
+		       const Elf64_Sym *symbols, size_t nsyms,
+		       const Elf64_Shdr *sections, size_t nsects, int *canonmap,
+		       const char *strings, size_t nstrings,
+		       const char *sh_name)
+{
+	struct {
+		uint64_t	r_offset;
+		uint64_t	st_value;
+		uint64_t	st_size;
+		uint32_t	r_type;
+		uint16_t	st_shndx;
+		uint8_t		st_info;
+		uint8_t		st_other;
+
+	} __attribute__((packed)) relocation;
+
+	const Elf64_Sym *symbol;
+	size_t loop;
+
+	/* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+	for (loop = 0; loop < nrels; loop++) {
+		Elf64_Section st_shndx;
+		Elf64_Xword r_info;
+
+		/* decode the relocation */
+		r_info = get64(&relatab[loop].r_info);
+		relocation.r_offset = relatab[loop].r_offset;
+		set32(&relocation.r_type, ELF64_R_TYPE(r_info));
+
+		if (ELF64_R_SYM(r_info) >= nsyms) {
+			fprintf(stderr, "Invalid symbol ID %lx in relocation %zi\n",
+				ELF64_R_SYM(r_info), loop);
+			exit(1);
+		}
+
+		/* decode the symbol referenced by the relocation */
+		symbol = &symbols[ELF64_R_SYM(r_info)];
+		relocation.st_info = symbol->st_info;
+		relocation.st_other = symbol->st_other;
+		relocation.st_value = symbol->st_value;
+		relocation.st_size = symbol->st_size;
+		relocation.st_shndx = symbol->st_shndx;
+		st_shndx = get16(&symbol->st_shndx);
+
+		/* canonicalise the section used by the symbol */
+		if (st_shndx > SHN_UNDEF && st_shndx < nsects)
+			set16(&relocation.st_shndx, canonmap[st_shndx]);
+
+		write_out_val(relocation);
+
+		/* undefined symbols must be named if referenced */
+		if (st_shndx == SHN_UNDEF) {
+			const char *name = strings + get32(&symbol->st_name);
+			write_out(name, strlen(name) + 1);
+		}
+	}
+
+	verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
+
+} /* end extract_elf64_rel() */
+
+/*****************************************************************************/
+/*
+ * extract the data from a 64-bit module
+ */
+void extract_elf64(void *buffer, size_t len, Elf64_Ehdr *hdr)
+{
+	const Elf64_Sym *symbols;
+	Elf64_Shdr *sections;
+	const char *secstrings, *strings;
+	size_t nsyms, nstrings;
+	int loop, shnum, *canonlist, *canonmap, canon, changed, tmp;
+
+	sections = buffer + get64(&hdr->e_shoff);
+	secstrings = buffer + get64(&sections[get16(&hdr->e_shstrndx)].sh_offset);
+	shnum = get16(&hdr->e_shnum);
+
+	/* find the symbol table and the string table and produce a list of
+	 * index numbers of sections that contribute to the kernel's module
+	 * image
+	 */
+	canonlist = calloc(sizeof(int), shnum * 2);
+	if (!canonlist) {
+		perror("calloc");
+		exit(1);
+	}
+	canonmap = canonlist + shnum;
+	canon = 0;
+
+	symbols = NULL;
+	strings = NULL;
+
+	for (loop = 1; loop < shnum; loop++) {
+		const char *sh_name = secstrings + get32(&sections[loop].sh_name);
+		Elf64_Word  sh_type	= get32(&sections[loop].sh_type);
+		Elf64_Xword sh_size	= get64(&sections[loop].sh_size);
+		Elf64_Xword sh_flags	= get64(&sections[loop].sh_flags);
+		Elf64_Off   sh_offset	= get64(&sections[loop].sh_offset);
+		void *data = buffer + sh_offset;
+
+		/* quick sanity check */
+		if (sh_type != SHT_NOBITS && len < sh_offset + sh_size) {
+			fprintf(stderr, "Section goes beyond EOF\n");
+			exit(3);
+		}
+
+		/* we only need to canonicalise allocatable sections */
+		if (sh_flags & SHF_ALLOC)
+			canonlist[canon++] = loop;
+
+		/* keep track of certain special sections */
+		switch (sh_type) {
+		case SHT_SYMTAB:
+			if (strcmp(sh_name, ".symtab") == 0) {
+				symbols = data;
+				nsyms = sh_size / sizeof(Elf64_Sym);
+			}
+			break;
+
+		case SHT_STRTAB:
+			if (strcmp(sh_name, ".strtab") == 0) {
+				strings = data;
+				nstrings = sh_size;
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if (!symbols) {
+		fprintf(stderr, "Couldn't locate symbol table\n");
+		exit(3);
+	}
+
+	if (!strings) {
+		fprintf(stderr, "Couldn't locate strings table\n");
+		exit(3);
+	}
+
+	/* canonicalise the index numbers of the contributing section */
+	do {
+		changed = 0;
+
+		for (loop = 0; loop < canon - 1; loop++) {
+			const char *x = secstrings + get32(&sections[canonlist[loop + 0]].sh_name);
+			const char *y = secstrings + get32(&sections[canonlist[loop + 1]].sh_name);
+			if (strcmp(x, y) > 0) {
+				tmp = canonlist[loop + 0];
+				canonlist[loop + 0] = canonlist[loop + 1];
+				canonlist[loop + 1] = tmp;
+				changed = 1;
+			}
+		}
+
+	} while(changed);
+
+	for (loop = 0; loop < canon; loop++)
+		canonmap[canonlist[loop]] = loop + 1;
+
+	if (is_verbose > 1) {
+		printf("\nSection canonicalisation map:\n");
+		for (loop = 1; loop < shnum; loop++) {
+			const char *x = secstrings + get32(&sections[loop].sh_name);
+			printf("%4d %s\n", canonmap[loop], x);
+		}
+
+		printf("\nAllocated section list in canonical order:\n");
+		for (loop = 0; loop < canon; loop++) {
+			const char *x = secstrings + get32(&sections[canonlist[loop]].sh_name);
+			printf("%4d %s\n", canonlist[loop], x);
+		}
+	}
+
+	memset(canonlist, 0, sizeof(int) * shnum);
+
+	/* iterate through the section table looking for sections we want to
+	 * contribute to the signature */
+	verbose("\n");
+	verbose("FILE POS CS SECT NAME\n");
+	verbose("======== == ==== ==============================\n");
+
+	for (loop = 1; loop < shnum; loop++) {
+		const char *sh_name = secstrings + get32(&sections[loop].sh_name);
+		Elf64_Word  sh_type	= get32(&sections[loop].sh_type);
+		Elf64_Xword sh_size	= get64(&sections[loop].sh_size);
+		Elf64_Xword sh_flags	= get64(&sections[loop].sh_flags);
+		Elf64_Word  sh_info	= get32(&sections[loop].sh_info);
+		Elf64_Off   sh_offset	= get64(&sections[loop].sh_offset);
+		void *data = buffer + sh_offset;
+
+		csum = 0;
+
+		/* include canonicalised relocation sections */
+		if (sh_type == SHT_REL || sh_type == SHT_RELA) {
+			if (sh_info <= 0 && sh_info >= hdr->e_shnum) {
+				fprintf(stderr,
+					"Invalid ELF - REL/RELA sh_info does"
+					" not refer to a valid section\n");
+				exit(3);
+			}
+
+			if (canonlist[sh_info]) {
+				Elf32_Word xsh_info;
+
+				verbose("%08lx ", ftell(outfd));
+
+				set32(&xsh_info, canonmap[sh_info]);
+
+				/* write out selected portions of the section
+				 * header */
+				write_out(sh_name, strlen(sh_name));
+				write_out_val(sections[loop].sh_type);
+				write_out_val(sections[loop].sh_flags);
+				write_out_val(sections[loop].sh_size);
+				write_out_val(sections[loop].sh_addralign);
+				write_out_val(xsh_info);
+
+				if (sh_type == SHT_RELA)
+					extract_elf64_rela(buffer, loop, sh_info,
+							   data, sh_size / sizeof(Elf64_Rela),
+							   symbols, nsyms,
+							   sections, shnum, canonmap,
+							   strings, nstrings,
+							   sh_name);
+				else
+					extract_elf64_rel(buffer, loop, sh_info,
+							  data, sh_size / sizeof(Elf64_Rel),
+							  symbols, nsyms,
+							  sections, shnum, canonmap,
+							  strings, nstrings,
+							  sh_name);
+			}
+
+			continue;
+		}
+
+		/* include allocatable loadable sections */
+		if (sh_type != SHT_NOBITS && sh_flags & SHF_ALLOC)
+			goto include_section;
+
+		/* not this section */
+		continue;
+
+	include_section:
+		verbose("%08lx ", ftell(outfd));
+
+		/* write out selected portions of the section header */
+		write_out(sh_name, strlen(sh_name));
+		write_out_val(sections[loop].sh_type);
+		write_out_val(sections[loop].sh_flags);
+		write_out_val(sections[loop].sh_size);
+		write_out_val(sections[loop].sh_addralign);
+
+		/* write out the section data */
+		write_out(data, sh_size);
+
+		verbose("%02x %4d %s\n", csum, loop, sh_name);
+
+		/* note the section has been written */
+		canonlist[loop] = 1;
+	}
+
+	verbose("%08lx         (%lu bytes csum 0x%02x)\n",
+		ftell(outfd), ftell(outfd), xcsum);
+
+} /* end extract_elf64() */
+
+/*****************************************************************************/
+/*
+ * extract a RELA table
+ * - need to canonicalise the entries in case section addition/removal has
+ *   rearranged the symbol table and the section table
+ */
+void extract_elf32_rela(const void *buffer, int secix, int targetix,
+			const Elf32_Rela *relatab, size_t nrels,
+			const Elf32_Sym *symbols, size_t nsyms,
+			const Elf32_Shdr *sections, size_t nsects, int *canonmap,
+			const char *strings, size_t nstrings,
+			const char *sh_name)
+{
+	struct {
+		uint32_t	r_offset;
+		uint32_t	r_addend;
+		uint32_t	st_value;
+		uint32_t	st_size;
+		uint16_t	st_shndx;
+		uint8_t		r_type;
+		uint8_t		st_info;
+		uint8_t		st_other;
+
+	} __attribute__((packed)) relocation;
+
+	const Elf32_Sym *symbol;
+	size_t loop;
+
+	/* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+	for (loop = 0; loop < nrels; loop++) {
+		Elf32_Section st_shndx;
+		Elf32_Word r_info;
+
+		/* decode the relocation */
+		r_info = get32(&relatab[loop].r_info);
+		relocation.r_offset = relatab[loop].r_offset;
+		relocation.r_addend = relatab[loop].r_addend;
+		relocation.r_type = ELF32_R_TYPE(r_info);
+
+		if (ELF32_R_SYM(r_info) >= nsyms) {
+			fprintf(stderr, "Invalid symbol ID %x in relocation %zu\n",
+				ELF32_R_SYM(r_info), loop);
+			exit(1);
+		}
+
+		/* decode the symbol referenced by the relocation */
+		symbol = &symbols[ELF32_R_SYM(r_info)];
+		relocation.st_info = symbol->st_info;
+		relocation.st_other = symbol->st_other;
+		relocation.st_value = symbol->st_value;
+		relocation.st_size = symbol->st_size;
+		relocation.st_shndx = symbol->st_shndx;
+		st_shndx = get16(&symbol->st_shndx);
+
+		/* canonicalise the section used by the symbol */
+		if (st_shndx > SHN_UNDEF && st_shndx < nsects)
+			set16(&relocation.st_shndx, canonmap[st_shndx]);
+
+		write_out_val(relocation);
+
+		/* undefined symbols must be named if referenced */
+		if (st_shndx == SHN_UNDEF) {
+			const char *name = strings + get32(&symbol->st_name);
+			write_out(name, strlen(name) + 1);
+		}
+	}
+
+	verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
+
+} /* end extract_elf32_rela() */
+
+/*****************************************************************************/
+/*
+ * extract a REL table
+ * - need to canonicalise the entries in case section addition/removal has
+ *   rearranged the symbol table and the section table
+ */
+void extract_elf32_rel(const void *buffer, int secix, int targetix,
+		       const Elf32_Rel *relatab, size_t nrels,
+		       const Elf32_Sym *symbols, size_t nsyms,
+		       const Elf32_Shdr *sections, size_t nsects, int *canonmap,
+		       const char *strings, size_t nstrings,
+		       const char *sh_name)
+{
+	struct {
+		uint32_t	r_offset;
+		uint32_t	st_value;
+		uint32_t	st_size;
+		uint16_t	st_shndx;
+		uint8_t		r_type;
+		uint8_t		st_info;
+		uint8_t		st_other;
+
+	} __attribute__((packed)) relocation;
+
+	const Elf32_Sym *symbol;
+	size_t loop;
+
+	/* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+	for (loop = 0; loop < nrels; loop++) {
+		Elf32_Section st_shndx;
+		Elf32_Word r_info;
+
+		/* decode the relocation */
+		r_info = get32(&relatab[loop].r_info);
+		relocation.r_offset = relatab[loop].r_offset;
+		relocation.r_type = ELF32_R_TYPE(r_info);
+
+		if (ELF32_R_SYM(r_info) >= nsyms) {
+			fprintf(stderr, "Invalid symbol ID %x in relocation %zu\n",
+				ELF32_R_SYM(r_info), loop);
+			exit(1);
+		}
+
+		/* decode the symbol referenced by the relocation */
+		symbol = &symbols[ELF32_R_SYM(r_info)];
+		relocation.st_info = symbol->st_info;
+		relocation.st_other = symbol->st_other;
+		relocation.st_value = symbol->st_value;
+		relocation.st_size = symbol->st_size;
+		relocation.st_shndx = symbol->st_shndx;
+		st_shndx = get16(&symbol->st_shndx);
+
+		/* canonicalise the section used by the symbol */
+		if (st_shndx > SHN_UNDEF && st_shndx < nsects)
+			set16(&relocation.st_shndx, canonmap[st_shndx]);
+		
+		write_out_val(relocation);
+
+		/* undefined symbols must be named if referenced */
+		if (st_shndx == SHN_UNDEF) {
+			const char *name = strings + get32(&symbol->st_name);
+			write_out(name, strlen(name) + 1);
+		}
+	}
+
+	verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
+
+} /* end extract_elf32_rel() */
+
+/*****************************************************************************/
+/*
+ * extract the data from a 32-bit module
+ */
+void extract_elf32(void *buffer, size_t len, Elf32_Ehdr *hdr)
+{
+	const Elf32_Sym *symbols;
+	Elf32_Shdr *sections;
+	const char *secstrings, *strings;
+	size_t nsyms, nstrings;
+	int loop, shnum, *canonlist, *canonmap, canon, changed, tmp;
+
+	sections = buffer + get32(&hdr->e_shoff);
+	secstrings = buffer + get32(&sections[get16(&hdr->e_shstrndx)].sh_offset);
+	shnum = get16(&hdr->e_shnum);
+
+	/* find the symbol table and the string table and produce a list of
+	 * index numbers of sections that contribute to the kernel's module
+	 * image
+	 */
+	canonlist = calloc(sizeof(int), shnum * 2);
+	if (!canonlist) {
+		perror("calloc");
+		exit(1);
+	}
+	canonmap = canonlist + shnum;
+	canon = 0;
+
+	symbols = NULL;
+	strings = NULL;
+
+	for (loop = 1; loop < shnum; loop++) {
+		const char *sh_name = secstrings + get32(&sections[loop].sh_name);
+		Elf32_Word  sh_type	= get32(&sections[loop].sh_type);
+		Elf32_Xword sh_size	= get32(&sections[loop].sh_size);
+		Elf32_Xword sh_flags	= get32(&sections[loop].sh_flags);
+		Elf32_Off   sh_offset	= get32(&sections[loop].sh_offset);
+		void *data = buffer + sh_offset;
+
+		/* quick sanity check */
+		if (sh_type != SHT_NOBITS && len < sh_offset + sh_size) {
+			fprintf(stderr, "Section goes beyond EOF\n");
+			exit(3);
+		}
+
+		/* we only need to canonicalise allocatable sections */
+		if (sh_flags & SHF_ALLOC)
+			canonlist[canon++] = loop;
+
+		/* keep track of certain special sections */
+		switch (sh_type) {
+		case SHT_SYMTAB:
+			if (strcmp(sh_name, ".symtab") == 0) {
+				symbols = data;
+				nsyms = sh_size / sizeof(Elf32_Sym);
+			}
+			break;
+
+		case SHT_STRTAB:
+			if (strcmp(sh_name, ".strtab") == 0) {
+				strings = data;
+				nstrings = sh_size;
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if (!symbols) {
+		fprintf(stderr, "Couldn't locate symbol table\n");
+		exit(3);
+	}
+
+	if (!strings) {
+		fprintf(stderr, "Couldn't locate strings table\n");
+		exit(3);
+	}
+
+	/* canonicalise the index numbers of the contributing section */
+	do {
+		changed = 0;
+
+		for (loop = 0; loop < canon - 1; loop++) {
+			const char *x = secstrings + get32(&sections[canonlist[loop + 0]].sh_name);
+			const char *y = secstrings + get32(&sections[canonlist[loop + 1]].sh_name);
+			if (strcmp(x, y) > 0) {
+				tmp = canonlist[loop + 0];
+				canonlist[loop + 0] = canonlist[loop + 1];
+				canonlist[loop + 1] = tmp;
+				changed = 1;
+			}
+		}
+
+	} while(changed);
+
+	for (loop = 0; loop < canon; loop++)
+		canonmap[canonlist[loop]] = loop + 1;
+
+	if (is_verbose > 1) {
+		printf("\nSection canonicalisation map:\n");
+		for (loop = 1; loop < shnum; loop++) {
+			const char *x = secstrings + get32(&sections[loop].sh_name);
+			printf("%4d %s\n", canonmap[loop], x);
+		}
+
+		printf("\nAllocated section list in canonical order:\n");
+		for (loop = 0; loop < canon; loop++) {
+			const char *x = secstrings + get32(&sections[canonlist[loop]].sh_name);
+			printf("%4d %s\n", canonlist[loop], x);
+		}
+	}
+
+	memset(canonlist, 0, sizeof(int) * shnum);
+
+	/* iterate through the section table looking for sections we want to
+	 * contribute to the signature */
+	verbose("\n");
+	verbose("FILE POS CS SECT NAME\n");
+	verbose("======== == ==== ==============================\n");
+
+	for (loop = 1; loop < shnum; loop++) {
+		const char *sh_name = secstrings + get32(&sections[loop].sh_name);
+		Elf32_Word  sh_type	= get32(&sections[loop].sh_type);
+		Elf32_Xword sh_size	= get32(&sections[loop].sh_size);
+		Elf32_Xword sh_flags	= get32(&sections[loop].sh_flags);
+		Elf32_Word  sh_info	= get32(&sections[loop].sh_info);
+		Elf32_Off   sh_offset	= get32(&sections[loop].sh_offset);
+		void *data = buffer + sh_offset;
+
+		csum = 0;
+
+		/* quick sanity check */
+		if (sh_type != SHT_NOBITS && len < sh_offset + sh_size) {
+			fprintf(stderr, "section goes beyond EOF\n");
+			exit(3);
+		}
+
+		/* include canonicalised relocation sections */
+		if (sh_type == SHT_REL || sh_type == SHT_RELA) {
+			if (sh_info <= 0 && sh_info >= hdr->e_shnum) {
+				fprintf(stderr,
+					"Invalid ELF - REL/RELA sh_info does"
+					" not refer to a valid section\n");
+				exit(3);
+			}
+
+			if (canonlist[sh_info]) {
+				Elf32_Word xsh_info;
+
+				verbose("%08lx ", ftell(outfd));
+
+				set32(&xsh_info, canonmap[sh_info]);
+
+				/* write out selected portions of the section header */
+				write_out(sh_name, strlen(sh_name));
+				write_out_val(sections[loop].sh_type);
+				write_out_val(sections[loop].sh_flags);
+				write_out_val(sections[loop].sh_size);
+				write_out_val(sections[loop].sh_addralign);
+				write_out_val(xsh_info);
+
+				if (sh_type == SHT_RELA)
+					extract_elf32_rela(buffer, loop, sh_info,
+							   data, sh_size / sizeof(Elf32_Rela),
+							   symbols, nsyms,
+							   sections, shnum, canonmap,
+							   strings, nstrings,
+							   sh_name);
+				else
+					extract_elf32_rel(buffer, loop, sh_info,
+							  data, sh_size / sizeof(Elf32_Rel),
+							  symbols, nsyms,
+							  sections, shnum, canonmap,
+							  strings, nstrings,
+							  sh_name);
+			}
+
+			continue;
+		}
+
+		/* include allocatable loadable sections */
+		if (sh_type != SHT_NOBITS && sh_flags & SHF_ALLOC)
+			goto include_section;
+
+		/* not this section */
+		continue;
+
+	include_section:
+		verbose("%08lx ", ftell(outfd));
+
+		/* write out selected portions of the section header */
+		write_out(sh_name, strlen(sh_name));
+		write_out_val(sections[loop].sh_type);
+		write_out_val(sections[loop].sh_flags);
+		write_out_val(sections[loop].sh_size);
+		write_out_val(sections[loop].sh_addralign);
+
+		/* write out the section data */
+		write_out(data, sh_size);
+
+		verbose("%02x %4d %s\n", csum, loop, sh_name);
+
+		/* note the section has been written */
+		canonlist[loop] = 1;
+	}
+
+	verbose("%08lx         (%lu bytes csum 0x%02x)\n",
+		ftell(outfd), ftell(outfd), xcsum);
+
+} /* end extract_elf32() */
diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/modsign.sh linux-904/scripts/modsign/modsign.sh
--- linux-903/scripts/modsign/modsign.sh
+++ linux-904/scripts/modsign/modsign.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+###############################################################################
+#
+# Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+# Written by David Howells (dhowells at redhat.com)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+###############################################################################
+
+verbose=
+
+if [ $# -gt 1 -a "x$1" = "x-v" ]
+    then
+    verbose=-v
+    shift
+fi
+
+if [ $# = 0 ]
+    then
+	echo
+	echo "usage: $0 [-v] <module_to_sign> [<key_name>]"
+	echo
+	exit 1
+fi
+
+module=$1
+
+if [ -z "$KEYFLAGS" ]
+    then
+    KEYFLAGS="--no-default-keyring --secret-keyring ../kernel.sec --keyring ../kernel.pub"
+fi
+
+if [ $# -eq 2 ]
+    then
+    KEYFLAGS="$KEYFLAGS --default-key $2"
+fi
+
+# strip out only the sections that we care about
+scripts/modsign/mod-extract $verbose $module $module.out || exit $?
+
+# sign the sections
+gpg --no-greeting $KEYFLAGS -b $module.out || exit $?
+
+# check the signature
+#gpg --verify rxrpc.ko.out.sig rxrpc.ko.out
+
+## sha1 the sections
+#sha1sum $module.out | awk "{print \$1}" > $module.sha1
+
+# add the encrypted data to the module
+objcopy --add-section .module_sig=$module.out.sig $module $module.signed || exit $?
+objcopy --set-section-flags .module_sig=alloc $module.signed || exit $?
+rm -f $module.out*

linux-2.6-module_version.patch:
 linux-1720/drivers/block/DAC960.c           |    1 +
 linux-1720/drivers/block/cpqarray.c         |    1 +
 linux-1720/drivers/message/fusion/mptbase.c |    1 +
 linux-1720/drivers/net/b44.c                |    1 +
 linux-1720/drivers/net/ns83820.c            |    1 +
 linux-1720/drivers/net/tg3.c                |    1 +
 linux-1720/drivers/scsi/gdth.c              |    1 +
 linux-2.6.13/drivers/block/cciss.c          |    1 +
 8 files changed, 8 insertions(+)

--- NEW FILE linux-2.6-module_version.patch ---
--- linux-2.6.13/drivers/block/cciss.c~	2005-09-16 04:56:37.000000000 -0400
+++ linux-2.6.13/drivers/block/cciss.c	2005-09-16 04:56:47.000000000 -0400
@@ -56,6 +56,7 @@ MODULE_DESCRIPTION("Driver for HP Contro
 MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
 			" SA6i P600 P800 P400 P400i E200 E200i");
 MODULE_LICENSE("GPL");
+MODULE_VERSION("2.6.8");
 
 #include "cciss_cmd.h"
 #include "cciss.h"
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/block/cpqarray.c linux-1720/drivers/block/cpqarray.c
--- linux-1700/drivers/block/cpqarray.c
+++ linux-1720/drivers/block/cpqarray.c
@@ -52,6 +52,7 @@
 /* Original author Chris Frantz - Compaq Computer Corporation */
 MODULE_AUTHOR("Compaq Computer Corporation");
 MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.6.0");
+MODULE_VERSION("2.6.0");
 MODULE_LICENSE("GPL");
 
 #include "cpqarray.h"
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/block/DAC960.c linux-1720/drivers/block/DAC960.c
--- linux-1700/drivers/block/DAC960.c
+++ linux-1720/drivers/block/DAC960.c
@@ -7109,3 +7109,4 @@ module_init(DAC960_init_module);
 module_exit(DAC960_cleanup_module);
 
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DAC960_DriverVersion);
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/message/fusion/mptbase.c linux-1720/drivers/message/fusion/mptbase.c
--- linux-1700/drivers/message/fusion/mptbase.c
+++ linux-1720/drivers/message/fusion/mptbase.c
@@ -119,6 +119,7 @@
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
+MODULE_VERSION(MPT_LINUX_VERSION_COMMON);
 
 /*
  *  cmd line parameters
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/net/b44.c linux-1720/drivers/net/b44.c
--- linux-1700/drivers/net/b44.c
+++ linux-1720/drivers/net/b44.c
@@ -85,6 +85,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
 static int b44_debug = -1;	/* -1 == use B44_DEF_MSG_ENABLE as value */
 module_param(b44_debug, int, 0);
 MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
+MODULE_VERSION(DRV_MODULE_VERSION);
 
 static struct pci_device_id b44_pci_tbl[] = {
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/net/ns83820.c linux-1720/drivers/net/ns83820.c
--- linux-1700/drivers/net/ns83820.c
+++ linux-1720/drivers/net/ns83820.c
@@ -2206,6 +2206,7 @@ static void __exit ns83820_exit(void)
 MODULE_AUTHOR("Benjamin LaHaise <bcrl at kvack.org>");
 MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(VERSION);
 
 MODULE_DEVICE_TABLE(pci, ns83820_pci_tbl);
 
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/net/tg3.c linux-1720/drivers/net/tg3.c
--- linux-1700/drivers/net/tg3.c
+++ linux-1720/drivers/net/tg3.c
@@ -146,6 +146,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
 static int tg3_debug = -1;	/* -1 == use TG3_DEF_MSG_ENABLE as value */
 module_param(tg3_debug, int, 0);
 MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value");
+MODULE_VERSION(DRV_MODULE_VERSION);
 
 static struct pci_device_id tg3_pci_tbl[] = {
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700,
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/scsi/gdth.c linux-1720/drivers/scsi/gdth.c
--- linux-1700/drivers/scsi/gdth.c
+++ linux-1720/drivers/scsi/gdth.c
@@ -656,6 +656,7 @@ module_param(probe_eisa_isa, int, 0);
 module_param(force_dma32, int, 0);
 MODULE_AUTHOR("Achim Leubner");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(GDTH_VERSION_STR);
 
 /* ioctl interface */
 static struct file_operations gdth_fops = {

linux-2.6-net-sundance-ip100A.patch:
 sundance.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-net-sundance-ip100A.patch ---
--- linux-2.6.11/drivers/net/sundance.c~	2005-05-06 15:11:22.000000000 -0400
+++ linux-2.6.11/drivers/net/sundance.c	2005-05-06 15:12:22.000000000 -0400
@@ -282,6 +282,7 @@ static struct pci_device_id sundance_pci
 	{0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3},
 	{0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
 	{0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+	{0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
@@ -299,7 +300,8 @@ static struct pci_id_info pci_id_tbl[] =
 	{"D-Link DFE-580TX 4 port Server Adapter"},
 	{"D-Link DFE-530TXS FAST Ethernet Adapter"},
 	{"D-Link DL10050-based FAST Ethernet Adapter"},
-	{"Sundance Technology Alta"},
+	{"IC Plus IP100 Fast Ethernet Adapter"},
+	{"IC Plus IP100A Fast Ethernet Adapter" },
 	{NULL,},			/* 0 terminated list. */
 };
 

linux-2.6-netconsole.patch:
 netconsole.c |  121 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 106 insertions(+), 15 deletions(-)

--- NEW FILE linux-2.6-netconsole.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1501/drivers/net/netconsole.c linux-1502/drivers/net/netconsole.c
--- linux-1501/drivers/net/netconsole.c
+++ linux-1502/drivers/net/netconsole.c
@@ -45,6 +45,9 @@
 #include <linux/sysrq.h>
 #include <linux/smp.h>
 #include <linux/netpoll.h>
+#include <asm/unaligned.h>
+
+#include "netdump.h"
 
 MODULE_AUTHOR("Maintainer: Matt Mackall <mpm at selenic.com>");
 MODULE_DESCRIPTION("Console driver for network interfaces");
@@ -61,29 +61,100 @@ static struct netpoll np = {
 	.name = "netconsole",
 	.dev_name = "eth0",
 	.local_port = 6665,
-	.remote_port = 6666,
+	.remote_port = 514,
 	.remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
 	.drop = netpoll_queue,
 };
 static int configured = 0;
 
+static char netlog_config[256];
+module_param_string(netlog, netlog_config, 256, 0);
+MODULE_PARM_DESC(netlog, " netlog=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
+static struct netpoll netlog_np = {
+	.name = "netlog",
+	.dev_name = "eth0",
+	.local_port = 6664,
+	.remote_port = 6666,
+	.remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+};
+static int netlog_configured = 0;
+
 #define MAX_PRINT_CHUNK 1000
 
+#define SYSLOG_HEADER_LEN 4
+
+static int syslog_chars = SYSLOG_HEADER_LEN;
+static unsigned char syslog_line [MAX_PRINT_CHUNK + 10] = {
+	'<',
+	'5',
+	'>',
+	' ',
+	[4 ... MAX_PRINT_CHUNK+5] = '\0',
+};
+static unsigned char netlog_line[MAX_PRINT_CHUNK + HEADER_LEN];
+static unsigned int log_offset;
+
+/*
+ * We feed kernel messages char by char, and send the UDP packet
+ * one linefeed. We buffer all characters received.
+ */
+static inline void feed_syslog_char(const unsigned char c)
+{
+	if (syslog_chars == MAX_PRINT_CHUNK)
+		syslog_chars--;
+	syslog_line[syslog_chars] = c;
+	syslog_chars++;
+	if (c == '\n') {
+		netpoll_send_udp(&np, syslog_line, syslog_chars);
+		syslog_chars = SYSLOG_HEADER_LEN;
+	}
+}
+
 static void write_msg(struct console *con, const char *msg, unsigned int len)
 {
-	int frag, left;
+	int left, i;
 	unsigned long flags;
+	reply_t reply;
+	char *netlog_buf = &netlog_line[HEADER_LEN];
 
-	if (!np.dev)
+	if (!np.dev && !netlog_np.dev)
+		return;
+	if (unlikely(crashdump_mode()))
 		return;
 
 	local_irq_save(flags);
-
-	for(left = len; left; ) {
-		frag = min(left, MAX_PRINT_CHUNK);
-		netpoll_send_udp(&np, msg, frag);
-		msg += frag;
-		left -= frag;
+	if (np.dev)
+		for (i = 0; i < len; i++)
+			feed_syslog_char(msg[i]);
+
+	if (netlog_np.dev) {
+		left = len;
+		while (left) {
+			if (left > MAX_PRINT_CHUNK)
+				len = MAX_PRINT_CHUNK;
+			else
+				len = left;
+			netlog_line[0] = NETDUMP_VERSION;
+
+			reply.nr = 0;
+			reply.code = REPLY_LOG;
+			reply.info = log_offset;
+
+			put_unaligned(htonl(reply.nr), 
+				      (u32 *)(netlog_line + 1));
+			put_unaligned(htonl(reply.code),
+				      (u32 *)(netlog_line + 5));
+			put_unaligned(htonl(reply.info),
+				      (u32 *)(netlog_line + 9));
+
+			log_offset += len;
+			memcpy(netlog_buf, msg, len);
+
+			netpoll_send_udp(&netlog_np, 
+					 netlog_line, len + HEADER_LEN);
+			msg += len;
+			left -= len;
+		}
 	}
 
 	local_irq_restore(flags);
@@ -98,17 +173,29 @@ static int option_setup(char *opt)
 
 __setup("netconsole=", option_setup);
 
+static int netlog_option_setup(char *opt)
+{
+	netlog_configured = !netpoll_parse_options(&netlog_np, opt);
+	return 0;
+}
+
+__setup("netlog=", netlog_option_setup);
+
 static int init_netconsole(void)
 {
 	if(strlen(config))
 		option_setup(config);
 
-	if(!configured) {
-		printk("netconsole: not configured, aborting\n");
-		return -EINVAL;
-	}
+	if (strlen(netlog_config))
+		netlog_option_setup(netlog_config);
+
+	if (configured && netpoll_setup(&np))
+		printk("netconsole: failed to configure syslog service\n");
 
-	if(netpoll_setup(&np))
+	if (netlog_configured && netpoll_setup(&netlog_np))
+		printk("netconsole: failed to configured netlog service.\n");
+
+	if (!configured && !netlog_configured)
 		return -EINVAL;
 
 	register_console(&netconsole);
@@ -119,7 +206,12 @@ static int init_netconsole(void)
 static void cleanup_netconsole(void)
 {
 	unregister_console(&netconsole);
-	netpoll_cleanup(&np);
+
+	if (configured)
+		netpoll_cleanup(&np);
+
+	if (netlog_configured)
+		netpoll_cleanup(&netlog_np);
 }
 
 module_init(init_netconsole);

linux-2.6-netdump.patch:
 linux-2.6.12/drivers/net/Kconfig           |    7 
 linux-2.6.12/drivers/net/netdump.c         |  550 +++++++++++++++++++++++++++++
 linux-2.6.12/drivers/net/netdump.h         |   90 ++++
 linux-2.6.12/include/asm-generic/netdump.h |   48 ++
 linux-2.6.12/include/asm-i386/netdump.h    |   79 ++++
 linux-2.6.12/include/asm-ia64/netdump.h    |   82 ++++
 linux-2.6.12/include/asm-powerpc/netdump.h |   79 ++++
 linux-2.6.12/include/asm-s390/netdump.h    |    6 
 linux-2.6.12/include/asm-x86_64/netdump.h  |   79 ++++
 linux-2.6.12/include/linux/netdevice.h     |    8 
 linux-2.6.12/include/linux/netpoll.h       |    4 
 linux-2.6.12/net/core/netpoll.c            |   17 
 linux-2.6.14/drivers/net/Makefile          |    1 
 13 files changed, 1039 insertions(+), 11 deletions(-)

--- NEW FILE linux-2.6-netdump.patch ---
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/drivers/net/netdump.h	2005-08-19 17:47:33.033202480 -0400
@@ -0,0 +1,90 @@
+/*
+ *  linux/drivers/net/netdump.h
+ *
+ *  Copyright (C) 2001  Ingo Molnar <mingo at redhat.com>
+ *
+ *  This file contains the implementation of an IRQ-safe, crash-safe
+ *  kernel console implementation that outputs kernel messages to the
+ *  network.
+ *
+ * Modification history:
+ *
+ * 2001-09-17    started by Ingo Molnar.
+ */
+
+/****************************************************************
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2, or (at your option)
+ *      any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ****************************************************************/
+
+#define NETDUMP_VERSION 0x04
+
+#define NETDUMP_VERSION_MAX 0x5
+
+enum netdump_commands {
+	COMM_NONE = 0,
+	COMM_SEND_MEM = 1,
+	COMM_EXIT = 2,
+	COMM_REBOOT = 3,
+	COMM_HELLO = 4,
+	COMM_GET_NR_PAGES = 5,
+	COMM_GET_PAGE_SIZE = 6,
+	COMM_START_NETDUMP_ACK = 7,
+	COMM_GET_REGS = 8,
+	COMM_SHOW_STATE = 9,
+};
+
+#define NETDUMP_REQ_SIZE (8+4*4)
+
+typedef struct netdump_req_s {
+	u64 magic;
+	u32 nr;
+	u32 command;
+	u32 from;
+	u32 to;
+	struct list_head list; 
+} req_t;
+
+enum netdump_replies {
+	REPLY_NONE = 0,
+	REPLY_ERROR = 1,
+	REPLY_LOG = 2,
+	REPLY_MEM = 3,
+	REPLY_RESERVED = 4,
+	REPLY_HELLO = 5,
+	REPLY_NR_PAGES = 6,
+	REPLY_PAGE_SIZE = 7,
+	REPLY_START_NETDUMP = 8,
+	REPLY_END_NETDUMP = 9,
+	REPLY_REGS = 10,
+	REPLY_MAGIC = 11,
+	REPLY_SHOW_STATE = 12,
+};
+
+typedef struct netdump_reply_s {
+	u32 nr;
+	u32 code;
+	u32 info;
+} reply_t;
+
+#define HEADER_LEN (1 + sizeof(reply_t))
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+#define netdump_mdelay(n) (                             \
+        {                                               \
+                unsigned long __ms=(n);                 \
+                while (__ms--) udelay(1000);            \
+        })
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/drivers/net/netdump.c	2005-08-19 17:47:33.024203976 -0400
@@ -0,0 +1,550 @@
+/*
+ *  linux/drivers/net/netdump.c
+ *
+ *  Copyright (C) 2001  Ingo Molnar <mingo at redhat.com>
+ *  Copyright (C) 2002  Red Hat, Inc.
+ *  Copyright (C) 2004  Red Hat, Inc.
+ *
+ *  This file contains the implementation of an IRQ-safe, crash-safe
+ *  kernel console implementation that outputs kernel messages to the
+ *  network.
+ *
+ * Modification history:
+ *
+ * 2001-09-17    started by Ingo Molnar.
+ * 2002-03-14    simultaneous syslog packet option by Michael K. Johnson
+ * 2004-04-07    port to 2.6 netpoll facility by Dave Anderson and Jeff Moyer.
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/reboot.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <asm/unaligned.h>
+#include <asm/pgtable.h>
+#include <linux/console.h>
+#include <linux/smp_lock.h>
+#include <linux/elf.h>
+#include <linux/preempt.h>
+
+#include "netdump.h"
+#include <linux/netpoll.h>
+
+/*
+ *  prototypes.
+ */
+void netdump_rx(struct netpoll *np, short source, char *data, int dlen);
+static void send_netdump_msg(struct netpoll *np, const char *msg, unsigned int msg_len, reply_t *reply);
+static void send_netdump_mem(struct netpoll *np, req_t *req);
+static void netdump_startup_handshake(struct netpoll *np);
+static asmlinkage void netpoll_netdump(struct pt_regs *regs, void *arg);
+static void netpoll_start_netdump(struct pt_regs *regs);
+
+
+#include <asm/netdump.h>
+
+
+#undef Dprintk
+#define DEBUG 0
+#if DEBUG
+# define Dprintk(x...) printk(KERN_INFO x)
+#else
+# define Dprintk(x...)
+#endif
+
+MODULE_AUTHOR("Maintainer: Dave Anderson <anderson at redhat.com>");
+MODULE_DESCRIPTION("Network kernel crash dump module");
+MODULE_LICENSE("GPL");
+
+static char config[256];
+module_param_string(netdump, config, 256, 0);
+MODULE_PARM_DESC(netdump, 
+     " netdump=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
+
+static u32 magic1, magic2;
+module_param(magic1, uint, 000);
+module_param(magic2, uint, 000);
+
+static struct netpoll np = {
+	.name = "netdump",
+	.dev_name = "eth0",
+	.local_port = 6666,
+	.remote_port = 6666,
+	.remote_mac = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	.rx_hook = netdump_rx,
+	.dump_func = netpoll_start_netdump,
+};
+
+
+/*
+ * NOTE: security depends on the trusted path between the netconsole
+ *       server and netconsole client, since none of the packets are
+ *       encrypted. The random magic number protects the protocol
+ *       against spoofing.
+ */
+static u64 netdump_magic;
+
+static spinlock_t req_lock = SPIN_LOCK_UNLOCKED;
+static int nr_req = 0;
+static LIST_HEAD(request_list);
+
+static unsigned long long t0, jiffy_cycles = 1000 * (1000000/HZ);
+void *netdump_stack;
+
+
+static void update_jiffies(void)
+{
+	static unsigned long long prev_tick;
+	platform_timestamp(t0);
+
+	/* maintain jiffies in a polling fashion, based on rdtsc. */
+	if (t0 - prev_tick >= jiffy_cycles) {
+		prev_tick += jiffy_cycles;
+		jiffies++;
+	}
+}
+
+static void add_new_req(req_t *req)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&req_lock, flags);
+	list_add_tail(&req->list, &request_list);
+	nr_req++;
+	Dprintk("pending requests: %d.\n", nr_req);
+	spin_unlock_irqrestore(&req_lock, flags);
+}
+
+static req_t *get_new_req(void)
+{
+	req_t *req = NULL;
+	unsigned long flags;
+
+	update_jiffies();
+
+	spin_lock_irqsave(&req_lock, flags);
+	if (nr_req) {
+		req = list_entry(request_list.next, req_t, list);
+		list_del(&req->list);
+		nr_req--;
+	}
+	spin_unlock_irqrestore(&req_lock, flags);
+
+	return req;
+}
+
+static req_t *alloc_req(void)
+{
+	req_t *req;
+
+	req = (req_t *) kmalloc(sizeof(*req), GFP_ATOMIC);
+	return req;
+}
+
+static inline void print_status (req_t *req)
+{
+	static int count = 0;
+	static unsigned long prev_jiffies = 0;
+
+	if (jiffies/HZ != prev_jiffies/HZ) {
+		prev_jiffies = jiffies;
+		count++;
+		switch (count & 3) {
+			case 0: printk("%d(%lu)/\r", nr_req, jiffies); break;
+			case 1: printk("%d(%lu)|\r", nr_req, jiffies); break;
+			case 2: printk("%d(%lu)\\\r", nr_req, jiffies); break;
+			case 3: printk("%d(%lu)-\r", nr_req, jiffies); break;
+		}
+	}
+}
+
+void netdump_rx(struct netpoll *np, short source, char *data, int dlen)
+{
+	req_t *req, *__req = (req_t *)data;
+
+	if (!netdump_mode)
+		return;
+#if DEBUG
+	{
+		static int packet_count;
+		Dprintk("        %d\r", ++packet_count);
+	}
+#endif
+
+	if (dlen < NETDUMP_REQ_SIZE) {
+		Dprintk("... netdump_rx: len not ok.\n");
+		return;
+	}
+
+	req = alloc_req();
+	if (!req) {
+		printk("no more RAM to allocate request - dropping it.\n");
+		return;
+	}
+
+	req->command = ntohl(__req->command);
+	req->from = ntohl(__req->from);
+	req->to = ntohl(__req->to);
+	req->nr = ntohl(__req->nr);
+
+	Dprintk("... netdump command: %08x.\n", req->command);
+	Dprintk("... netdump from:    %08x.\n", req->from);
+	Dprintk("... netdump to:      %08x.\n", req->to);
+
+	add_new_req(req);
+	return;
+}
+
+#define MAX_MSG_LEN HEADER_LEN + 1024
+
+static unsigned char effective_version = NETDUMP_VERSION;
+
+static void send_netdump_msg(struct netpoll *np, const char *msg, unsigned int msg_len, reply_t *reply)
+{
+	/* max len should be 1024 + HEADER_LEN */
+	static unsigned char netpoll_msg[MAX_MSG_LEN + 1];
+
+	if (msg_len + HEADER_LEN > MAX_MSG_LEN + 1) {
+		printk("CODER ERROR!!! msg_len %ud too big for send msg\n",
+		       msg_len);
+		for (;;) local_irq_disable();
+		/* NOTREACHED */
+	}
+
+	netpoll_msg[0] = effective_version;
+	put_unaligned(htonl(reply->nr), (u32 *) (&netpoll_msg[1]));
+	put_unaligned(htonl(reply->code), (u32 *) (&netpoll_msg[5]));
+	put_unaligned(htonl(reply->info), (u32 *) (&netpoll_msg[9]));
+	memcpy(&netpoll_msg[HEADER_LEN], msg, msg_len);
+
+	netpoll_send_udp(np, netpoll_msg, HEADER_LEN + msg_len);
+}
+
+static void send_netdump_mem(struct netpoll *np, req_t *req)
+{
+	int i;
+	char *kaddr;
+	char str[1024];
+	struct page *page = NULL;
+	unsigned long nr = req->from;
+	int nr_chunks = PAGE_SIZE/1024;
+	reply_t reply;
+	
+	Dprintk(" ... send_netdump_mem\n");
+	reply.nr = req->nr;
+	reply.info = 0;
+	if (req->from >= platform_max_pfn()) {
+		sprintf(str, "page %08lx is bigger than max page # %08lx!\n", 
+			nr, platform_max_pfn());
+		reply.code = REPLY_ERROR;
+		send_netdump_msg(np, str, strlen(str), &reply);
+		return;
+	}
+	if (platform_page_is_ram(nr)) {
+		page = pfn_to_page(nr);
+		if (page_to_pfn(page) != nr)
+			page = NULL;
+	}
+	if (!page) {
+		reply.code = REPLY_RESERVED;
+		reply.info = platform_next_available(nr);
+		send_netdump_msg(np, str, 0, &reply);
+		return;
+	}
+
+	kaddr = (char *)kmap_atomic(page, KM_CRASHDUMP);
+
+	for (i = 0; i < nr_chunks; i++) {
+		unsigned int offset = i*1024;
+		reply.code = REPLY_MEM;
+		reply.info = offset;
+		Dprintk(" ... send_netdump_mem: sending message\n");
+		send_netdump_msg(np, kaddr + offset, 1024, &reply);
+		Dprintk(" ... send_netdump_mem: sent message\n");
+	}
+
+	kunmap_atomic(kaddr, KM_CRASHDUMP);
+	Dprintk(" ... send_netdump_mem: returning\n");
+}
+
+/*
+ * This function waits for the client to acknowledge the receipt
+ * of the netdump startup reply, with the possibility of packets
+ * getting lost. We resend the startup packet if no ACK is received,
+ * after a 1 second delay.
+ *
+ * (The client can test the success of the handshake via the HELLO
+ * command, and send ACKs until we enter netdump mode.)
+ */
+static void netdump_startup_handshake(struct netpoll *np)
+{
+	char tmp[200];
+	reply_t reply;
+	req_t *req = NULL;
+	int i;
+
+repeat:
+	sprintf(tmp,
+   	    "task_struct:0x%lx page_offset:0x%llx netdump_magic:0x%llx\n",
+		(unsigned long)current, (unsigned long long)PAGE_OFFSET, 
+		(unsigned long long)netdump_magic);
+	reply.code = REPLY_START_NETDUMP;
+	reply.nr = platform_machine_type();
+	reply.info = NETDUMP_VERSION_MAX;
+
+	send_netdump_msg(np, tmp, strlen(tmp), &reply);
+
+	for (i = 0; i < 10000; i++) {
+		// wait 1 sec.
+		udelay(100);
+		Dprintk("handshake: polling controller ...\n");
+		netpoll_poll(np);
+		req = get_new_req();
+		if (req)
+			break;
+	}
+	if (!req)
+		goto repeat;
+	if (req->command != COMM_START_NETDUMP_ACK) {
+		kfree(req);
+		goto repeat;
+	}
+
+	/*
+	 *  Negotiate an effective version that works with the server. 
+	 */
+	if ((effective_version = platform_effective_version(req)) == 0) {
+		printk(KERN_ERR
+			"netdump: server cannot handle this client -- rebooting.\n");
+		netdump_mdelay(3000);
+		machine_restart(NULL);
+	}
+
+	kfree(req);
+
+	printk("NETDUMP START!\n");
+}
+
+static char cpus_frozen[NR_CPUS] = { 0 }; 
+
+static void freeze_cpu (void * dummy)
+{
+	cpus_frozen[smp_processor_id()] = 1;
+	platform_freeze_cpu();
+}
+
+static void netpoll_start_netdump(struct pt_regs *regs)
+{
+	int i;
+	unsigned long flags;
+
+	/*
+	 *  The netdump code is not re-entrant for several reasons.  Most
+	 *  immediately, we will switch to the base of our stack and 
+	 *  overwrite all of our call history.
+	 */
+	if (netdump_mode) {
+		printk(KERN_ERR
+		"netpoll_start_netdump: called recursively.  rebooting.\n");
+		netdump_mdelay(3000);
+		machine_restart(NULL);
+	}
+	netdump_mode = 1;
+
+	local_irq_save(flags);
+	preempt_disable();
+
+	smp_call_function(freeze_cpu, NULL, 1, -1);
+	netdump_mdelay(3000);
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpus_frozen[i])
+			printk("CPU#%d is frozen.\n", i);
+		else if (i == smp_processor_id())
+			printk("CPU#%d is executing netdump.\n", i);
+	}
+
+	/*
+	 *  Some platforms may want to execute netdump on its own stack.
+	 */
+	platform_start_crashdump(netdump_stack, netpoll_netdump, regs);
+
+	preempt_enable_no_resched();
+	local_irq_restore(flags);
+	return;
+}
+
+static char command_tmp[1024];
+
+static asmlinkage void netpoll_netdump(struct pt_regs *regs, void *platform_arg)
+{
+	reply_t reply;
+	char *tmp = command_tmp;
+	extern unsigned long totalram_pages;
+	struct pt_regs myregs;
+	req_t *req;
+
+	/*
+	 * Just in case we are crashing within the networking code
+	 * ... attempt to fix up.
+	 */
+	netpoll_reset_locks(&np);
+	platform_fix_regs();
+	platform_timestamp(t0);
+	netpoll_set_trap(1); /* bypass networking stack */
+
+	printk("< netdump activated - performing handshake with the server. >\n");
+	netdump_startup_handshake(&np);
+
+	printk("< handshake completed - listening for dump requests. >\n");
+
+	while (netdump_mode) {
+		local_irq_disable();
+		Dprintk("main netdump loop: polling controller ...\n");
+		netpoll_poll(&np);
+
+		req = get_new_req();
+		if (!req)
+			continue;
+
+		Dprintk("got new req, command %d.\n", req->command);
+		print_status(req);
+		switch (req->command) {
+		case COMM_NONE:
+			Dprintk("got NO command.\n");
+			break;
+
+		case COMM_SEND_MEM:
+			Dprintk("got MEM command.\n");
+			send_netdump_mem(&np, req);
+			break;
+
+		case COMM_EXIT:
+			Dprintk("got EXIT command.\n");
+			netdump_mode = 0;
+			netpoll_set_trap(0);
+			break;
+
+		case COMM_REBOOT:
+			Dprintk("got REBOOT command.\n");
+			printk("netdump: rebooting in 3 seconds.\n");
+			netdump_mdelay(3000);
+			machine_restart(NULL);
+			break;
+
+		case COMM_HELLO:
+			sprintf(tmp, "Hello, this is netdump version 0.%02d\n",
+				NETDUMP_VERSION);
+			reply.code = REPLY_HELLO;
+			reply.nr = req->nr;
+			reply.info = NETDUMP_VERSION;
+			send_netdump_msg(&np, tmp, strlen(tmp), &reply);
+			break;
+
+		case COMM_GET_PAGE_SIZE:
+			sprintf(tmp, "PAGE_SIZE: %ld\n", PAGE_SIZE);
+			reply.code = REPLY_PAGE_SIZE;
+			reply.nr = req->nr;
+			reply.info = PAGE_SIZE;
+			send_netdump_msg(&np, tmp, strlen(tmp), &reply);
+			break;
+
+		case COMM_GET_REGS:
+			reply.code = REPLY_REGS;
+			reply.nr = req->nr;
+			reply.info = (u32)totalram_pages;
+        		send_netdump_msg(&np, tmp,
+				platform_get_regs(tmp, &myregs), &reply);
+			break;
+
+		case COMM_GET_NR_PAGES:
+			reply.code = REPLY_NR_PAGES;
+			reply.nr = req->nr;
+			reply.info = platform_max_pfn();
+			sprintf(tmp, 
+				"Number of pages: %ld\n", platform_max_pfn());
+			send_netdump_msg(&np, tmp, strlen(tmp), &reply);
+			break;
+
+		case COMM_SHOW_STATE:
+			/* send response first */
+			reply.code = REPLY_SHOW_STATE;
+			reply.nr = req->nr;
+			reply.info = 0;
+
+			send_netdump_msg(&np, tmp, strlen(tmp), &reply);
+
+			netdump_mode = 0;
+			if (regs)
+				show_regs(regs);
+			show_state();
+			show_mem();
+			netdump_mode = 1;
+			break;
+
+		default:
+			reply.code = REPLY_ERROR;
+			reply.nr = req->nr;
+			reply.info = req->command;
+			Dprintk("got UNKNOWN command!\n");
+			sprintf(tmp, "Got unknown command code %d!\n", 
+				req->command);
+			send_netdump_msg(&np, tmp, strlen(tmp), &reply);
+			break;
+		}
+		kfree(req);
+		req = NULL;
+	}
+	sprintf(tmp, "NETDUMP end.\n");
+	reply.code = REPLY_END_NETDUMP;
+	reply.nr = 0;
+	reply.info = 0;
+	send_netdump_msg(&np, tmp, strlen(tmp), &reply);
+	printk("NETDUMP END!\n");
+}
+
+static int option_setup(char *opt)
+{
+	return !netpoll_parse_options(&np, opt);
+}
+
+__setup("netdump=", option_setup);
+
+static int init_netdump(void)
+{
+	int configured = 0;
+
+	if (strlen(config))
+		configured = option_setup(config);
+
+	if (!configured) {
+		printk(KERN_ERR "netdump: not configured, aborting\n");
+		return -EINVAL;
+	}
+
+	if (netpoll_setup(&np))
+		return -EINVAL;
+
+	if (magic1 || magic2)
+		netdump_magic = magic1 + (((u64)magic2)<<32);
+
+	/*
+	 *  Allocate a separate stack for netdump.
+	 */
+	platform_init_stack(&netdump_stack);
+
+	platform_jiffy_cycles(&jiffy_cycles);
+
+	printk(KERN_INFO "netdump: network crash dump enabled\n");
+	return 0;
+}
+
+static void cleanup_netdump(void)
+{
+	netpoll_cleanup(&np);
+	platform_cleanup_stack(netdump_stack);
+}
+
+module_init(init_netdump);
+module_exit(cleanup_netdump);
--- linux-2.6.12/drivers/net/Kconfig.netdump.orig	2005-08-19 17:45:43.052483533 -0400
+++ linux-2.6.12/drivers/net/Kconfig	2005-08-19 17:48:14.835252548 -0400
@@ -2545,6 +2545,13 @@ config NETCONSOLE
 	If you want to log kernel messages over the network, enable this.
 	See <file:Documentation/networking/netconsole.txt> for details.
 
+ config NETDUMP
+	tristate "Network kernel crash dump support"
+	depends on NETPOLL && NETPOLL_TRAP && (X86 || PPC_PSERIES || IA64)
+	---help---
+	Enable this option if you have a netdump server and you would like
+	to collect kernel crash dumps.
+
 endif #NETDEVICES
 
 config NETPOLL
--- linux-2.6.14/drivers/net/Makefile~	2005-10-30 21:44:17.000000000 -0500
+++ linux-2.6.14/drivers/net/Makefile	2005-10-30 21:44:33.000000000 -0500
@@ -203,6 +203,7 @@ obj-$(CONFIG_IRDA) += irda/
 obj-$(CONFIG_ETRAX_ETHERNET) += cris/
 
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
+obj-$(CONFIG_NETDUMP) += netdump.o
 
 obj-$(CONFIG_FS_ENET) += fs_enet/
 
--- linux-2.6.12/net/core/netpoll.c.netdump.orig	2005-08-19 17:46:01.104483015 -0400
+++ linux-2.6.12/net/core/netpoll.c	2005-08-19 17:47:33.034202314 -0400
@@ -20,10 +20,12 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/rcupdate.h>
+#include <linux/nmi.h>
 #include <linux/workqueue.h>
 #include <net/tcp.h>
 #include <net/udp.h>
 #include <asm/unaligned.h>
+#include <asm/byteorder.h>
 
 /*
  * We maintain a small pool of fully-sized skbs, to make sure the
@@ -132,7 +134,7 @@ static int checksum_udp(struct sk_buff *
 static void poll_napi(struct netpoll *np)
 {
 	struct netpoll_info *npinfo = np->dev->npinfo;
-	int budget = 16;
+	int budget = netdump_mode ? 64 : 16;
 
 	if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
 	    npinfo->poll_owner != smp_processor_id() &&
@@ -203,6 +205,7 @@ static void zap_completion_queue(void)
 	}
 
 	put_cpu_var(softnet_data);
+	touch_nmi_watchdog();
 }
 
 static struct sk_buff * find_skb(struct netpoll *np, int len, int reserve)
@@ -337,7 +340,7 @@ void netpoll_send_udp(struct netpoll *np
 	iph->check    = 0;
 	put_unaligned(htonl(np->local_ip), &(iph->saddr));
 	put_unaligned(htonl(np->remote_ip), &(iph->daddr));
-	iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
+	iph->check    = ip_fast_csum((unsigned char *)iph, 5);
 
 	eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
 
@@ -614,6 +617,9 @@ int netpoll_parse_options(struct netpoll
 	       np->remote_mac[4],
 	       np->remote_mac[5]);
 
+	if(np->dump_func)
+		netdump_func = np->dump_func;
+
 	return 0;
 
  parse_failed:
@@ -776,6 +782,12 @@ void netpoll_set_trap(int trap)
 		atomic_dec(&trapped);
 }
 
+void netpoll_reset_locks(struct netpoll *np)
+{
+	spin_lock_init(&skb_list_lock);
+	spin_lock_init(&np->dev->xmit_lock);
+}
+
 EXPORT_SYMBOL(netpoll_set_trap);
 EXPORT_SYMBOL(netpoll_trap);
 EXPORT_SYMBOL(netpoll_parse_options);
@@ -784,3 +796,4 @@ EXPORT_SYMBOL(netpoll_cleanup);
 EXPORT_SYMBOL(netpoll_send_udp);
 EXPORT_SYMBOL(netpoll_poll);
 EXPORT_SYMBOL(netpoll_queue);
+EXPORT_SYMBOL_GPL(netpoll_reset_locks);
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-ia64/netdump.h	2005-08-19 17:47:33.035202148 -0400
@@ -0,0 +1,82 @@
+#ifndef _ASM_IA64_NETDUMP_H_
+#define _ASM_IA64_NETDUMP_H_
+
+/*
+ * linux/include/asm-ia64/netdump.h
+ *
+ * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/crashdump.h>
+
+const static int platform_supports_netdump = 1;
+
+#define platform_machine_type() (EM_IA_64)
+
+#define platform_page_is_ram(x) page_is_ram(x)
+
+static inline unsigned char platform_effective_version(req_t *req)
+{
+	if (req->from > 0)
+		return min_t(unsigned char, req->from, NETDUMP_VERSION_MAX);
+	else
+		return 0;
+}
+
+extern void *high_memory;
+#define platform_max_pfn() ((__pa(high_memory)) / PAGE_SIZE)
+
+static inline u32 platform_next_available(unsigned long pfn)
+{
+	unsigned long pgnum = next_ram_page(pfn);
+
+	if (pgnum < platform_max_pfn()) {
+		return (u32)pgnum;
+	}
+	return 0;
+}
+
+static inline void platform_jiffy_cycles(unsigned long long *jcp)
+{
+        unsigned long long t0, t1;
+
+        platform_timestamp(t0);
+        netdump_mdelay(1);
+        platform_timestamp(t1);
+        if (t1 > t0)
+                *jcp = t1 - t0;
+}
+
+#define platform_freeze_cpu()                                  \
+{                                                              \
+       unw_init_running(ia64_freeze_cpu, 0);                   \
+}
+
+static inline unsigned int platform_get_regs(char *tmp, struct pt_regs *myregs)
+{
+	char *tmp2;
+
+	tmp2 = tmp + sprintf(tmp, "Sending register info.\n");
+	memcpy(tmp2, myregs, sizeof(struct pt_regs));
+
+	return(strlen(tmp) + sizeof(struct pt_regs));
+}
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IA64_NETDUMP_H */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-x86_64/netdump.h	2005-08-19 17:47:33.036201981 -0400
@@ -0,0 +1,79 @@
+#ifndef _ASM_X86_64_NETDUMP_H_
+#define _ASM_X86_64_NETDUMP_H_
+
+/*
+ * linux/include/asm-x86_64/netdump.h
+ *
+ * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/crashdump.h>
+
+const static int platform_supports_netdump = 1;
+
+#define platform_machine_type() (EM_X86_64)
+
+#define platform_page_is_ram(x) (page_is_ram(x) && \
+                kern_addr_valid((unsigned long)pfn_to_kaddr(x)))
+
+static inline unsigned char platform_effective_version(req_t *req)
+{
+	if (req->from > 0)
+		return min_t(unsigned char, req->from, NETDUMP_VERSION_MAX);
+	else
+		return 0;
+}
+
+#define platform_max_pfn() (num_physpages)
+
+static inline u32 platform_next_available(unsigned long pfn)
+{
+	unsigned long pgnum = next_ram_page(pfn);
+
+	if (pgnum < platform_max_pfn()) {
+		return (u32)pgnum;
+	}
+	return 0;
+}
+
+static inline void platform_jiffy_cycles(unsigned long long *jcp)
+{
+        unsigned long long t0, t1;
+
+        platform_timestamp(t0);
+        netdump_mdelay(1);
+        platform_timestamp(t1);
+        if (t1 > t0)
+                *jcp = t1 - t0;
+}
+
+static inline unsigned int platform_get_regs(char *tmp, struct pt_regs *myregs)
+{
+	elf_gregset_t elf_regs;
+	char *tmp2;
+
+	tmp2 = tmp + sprintf(tmp, "Sending register info.\n");
+	ELF_CORE_COPY_REGS(elf_regs, myregs);
+	memcpy(tmp2, &elf_regs, sizeof(elf_regs));
+
+	return(strlen(tmp) + sizeof(elf_regs));
+}
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_X86_64_NETDUMP_H */
--- linux-2.6.12/include/linux/netdevice.h.netdump.orig	2005-08-19 17:45:54.528576035 -0400
+++ linux-2.6.12/include/linux/netdevice.h	2005-08-19 17:47:33.040201316 -0400
@@ -596,20 +596,12 @@ static inline void netif_start_queue(str
 
 static inline void netif_wake_queue(struct net_device *dev)
 {
-#ifdef CONFIG_NETPOLL_TRAP
-	if (netpoll_trap())
-		return;
-#endif
 	if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
 		__netif_schedule(dev);
 }
 
 static inline void netif_stop_queue(struct net_device *dev)
 {
-#ifdef CONFIG_NETPOLL_TRAP
-	if (netpoll_trap())
-		return;
-#endif
 	set_bit(__LINK_STATE_XOFF, &dev->state);
 }
 
--- linux-2.6.12/include/linux/netpoll.h.netdump.orig	2005-08-19 17:46:01.045492820 -0400
+++ linux-2.6.12/include/linux/netpoll.h	2005-08-19 17:47:33.041201150 -0400
@@ -17,7 +17,8 @@ struct netpoll;
 struct netpoll {
 	struct net_device *dev;
 	char dev_name[16], *name;
-	void (*rx_hook)(struct netpoll *, int, char *, int);
+	void (*rx_hook)(struct netpoll *, short, char *, int);
+	void (*dump_func)(struct pt_regs *);
 	void (*drop)(struct sk_buff *skb);
 	u32 local_ip, remote_ip;
 	u16 local_port, remote_port;
@@ -42,6 +43,7 @@ void netpoll_set_trap(int trap);
 void netpoll_cleanup(struct netpoll *np);
 int __netpoll_rx(struct sk_buff *skb);
 void netpoll_queue(struct sk_buff *skb);
+void netpoll_reset_locks(struct netpoll *np);
 
 #ifdef CONFIG_NETPOLL
 static inline int netpoll_rx(struct sk_buff *skb)
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-generic/netdump.h	2005-08-19 17:47:33.042200984 -0400
@@ -0,0 +1,48 @@
+#ifndef _ASM_GENERIC_NETDUMP_H_
+#define _ASM_GENERIC_NETDUMP_H_
+
+/*
+ * linux/include/asm-generic/netdump.h
+ *
+ * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm-generic/crashdump.h>
+
+#ifdef __KERNEL__
+
+#warning netdump is not supported on this platform
+const static int platform_supports_netdump = 0;
+
+static inline int page_is_ram(unsigned long x) { return 0; }
+
+#define platform_machine_type() (EM_NONE)
+#define platform_effective_version(x) (0)
+#define platform_next_available(x) ((u32)0)
+#define platform_freeze_cpu()  do { } while (0)
+#define platform_jiffy_cycles(x)  do { } while (0)
+#define platform_max_pfn() (0)
+#define platform_get_regs(x,y) (0)
+
+#undef kmap_atomic
+#undef kunmap_atomic
+static inline char *kmap_atomic(void *page, int idx)  { return NULL; }
+#define kunmap_atomic(addr, idx)  do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_GENERIC_NETDUMP_H */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-powerpc/netdump.h	2005-08-19 17:47:33.036201981 -0400
@@ -0,0 +1,79 @@
+#ifndef _ASM_PPC64_NETDUMP_H_
+#define _ASM_PPC64_NETDUMP_H_
+
+/*
+ * linux/include/asm-powerpc/netdump.h
+ *
+ * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/crashdump.h>
+
+const static int platform_supports_netdump = 1;
+
+#define platform_page_is_ram(x) (page_is_ram(x))
+#define platform_machine_type() (EM_PPC64)
+
+static inline unsigned char platform_effective_version(req_t *req)
+{
+	if (req->from > 0)
+		return min_t(unsigned char, req->from, NETDUMP_VERSION_MAX);
+	else
+		return 0;
+}
+
+#define platform_max_pfn() (num_physpages)
+
+static inline u32 platform_next_available(unsigned long pfn)
+{
+	unsigned long pgnum = next_ram_page(pfn);
+
+	if (pgnum < platform_max_pfn()) {
+		return (u32)pgnum;
+	}
+	return 0;
+}
+
+static inline void platform_jiffy_cycles(unsigned long long *jcp)
+{
+       unsigned long long t0, t1;
+
+       platform_timestamp(t0);
+       netdump_mdelay(1);
+       platform_timestamp(t1);
+       if (t1 > t0)
+               *jcp = t1 - t0;
+}
+
+static inline unsigned int platform_get_regs(char *tmp, struct pt_regs *myregs)
+{
+	elf_gregset_t elf_regs;
+	char *tmp2;
+
+	tmp2 = tmp + sprintf(tmp, "Sending register info.\n");
+	ELF_CORE_COPY_REGS(elf_regs, myregs);
+	memcpy(tmp2, &elf_regs, sizeof(elf_regs));
+
+	return(strlen(tmp) + sizeof(elf_regs));
+}
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_PPC64_NETDUMP_H_ */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-i386/netdump.h	2005-08-19 17:47:33.037201815 -0400
@@ -0,0 +1,79 @@
+#ifndef _ASM_I386_NETDUMP_H_
+#define _ASM_I386_NETDUMP_H_
+
+/*
+ * linux/include/asm-i386/netdump.h
+ *
+ * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/irq.h>
+#include <asm/crashdump.h>
+
+const static int platform_supports_netdump = 1;
+
+#define platform_page_is_ram(x) (page_is_ram(x))
+#define platform_machine_type() (EM_386)
+
+static inline unsigned char platform_effective_version(req_t *req)
+{
+        if (req->from == 0)
+                return NETDUMP_VERSION;
+        else
+                return min_t(unsigned char, req->from, NETDUMP_VERSION_MAX);
+}
+
+#define platform_max_pfn() (num_physpages)
+
+static inline u32 platform_next_available(unsigned long pfn)
+{
+	unsigned long pgnum = next_ram_page(pfn);
+
+	if (pgnum < platform_max_pfn()) {
+		return (u32)pgnum;
+	}
+	return 0;
+}
+
+static inline void platform_jiffy_cycles(unsigned long long *jcp)
+{
+        unsigned long long t0, t1;
+
+        platform_timestamp(t0);
+        netdump_mdelay(1);
+        platform_timestamp(t1);
+        if (t1 > t0)
+                *jcp = t1 - t0;
+}
+
+static inline unsigned int platform_get_regs(char *tmp, struct pt_regs *myregs)
+{
+	elf_gregset_t elf_regs;
+	char *tmp2;
+
+	tmp2 = tmp + sprintf(tmp, "Sending register info.\n");
+	ELF_CORE_COPY_REGS(elf_regs, myregs);
+	memcpy(tmp2, &elf_regs, sizeof(elf_regs));
+
+	return(strlen(tmp) + sizeof(elf_regs));
+}
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_I386_NETDUMP_H_ */
--- /dev/null	2005-07-20 12:00:41.186496416 -0400
+++ linux-2.6.12/include/asm-s390/netdump.h	2005-08-19 17:47:33.043200818 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_S390_NETDUMP_H_
+#define _ASM_S390_NETDUMP_H_
+
+#include <asm-generic/netdump.h>
+
+#endif /* _ASM_S390_NETDUMP_H_ */

linux-2.6-obsolete-idescsi-warning.patch:
 ide-scsi.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-obsolete-idescsi-warning.patch ---

--- linux-2.6.11/drivers/scsi/ide-scsi.c~	2005-03-22 19:21:13.000000000 -0500
+++ linux-2.6.11/drivers/scsi/ide-scsi.c	2005-03-22 19:21:51.000000000 -0500
@@ -764,6 +764,8 @@ static ide_driver_t idescsi_driver = {
 	.drives			= LIST_HEAD_INIT(idescsi_driver.drives),
 };
 
+static int ide_scsi_warned;
+
 static int idescsi_ide_open(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -776,7 +778,10 @@ static int idescsi_ide_open(struct inode
 	drive = scsi->drive;
 
 	drive->usage++;
-
+	if (!ide_scsi_warned++) {
+		printk(KERN_WARNING "ide-scsi: Warning this device driver is only intended for specialist devices.\n");
+		printk(KERN_WARNING "ide-scsi: Do not use for cd burning, use /dev/hdX directly instead.\n");
+	}
 	return 0;
 }
 

linux-2.6-obsolete-oss-warning.patch:
 pcm_oss.c |    7 +++++++
 1 files changed, 7 insertions(+)

--- NEW FILE linux-2.6-obsolete-oss-warning.patch ---

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/sound/core/oss/pcm_oss.c linux-10000/sound/core/oss/pcm_oss.c
--- linux-3022/sound/core/oss/pcm_oss.c
+++ linux-10000/sound/core/oss/pcm_oss.c
@@ -1815,6 +1815,13 @@ static int snd_pcm_oss_open(struct inode
 	snd_pcm_oss_setup_t *psetup = NULL, *csetup = NULL;
 	int nonblock;
 	wait_queue_t wait;
+	static char printed_comm[16];
+
+	if (strncmp(printed_comm, current->comm, 16)) {
+		printk(KERN_DEBUG "application %s uses obsolete OSS audio interface\n",
+		       current->comm);
+		memcpy(printed_comm, current->comm, 16);
+	}
 
 	snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
 	device = SNDRV_MINOR_OSS_DEVICE(minor) == SNDRV_MINOR_OSS_PCM1 ?

linux-2.6-optimise-for-size.patch:
 Kconfig |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-optimise-for-size.patch ---
MAke this selectable without EMBEDDED

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/init/Kconfig linux-10000/init/Kconfig
--- linux-3022/init/Kconfig
+++ linux-10000/init/Kconfig
@@ -291,7 +291,7 @@ config EPOLL
 	  support for epoll family of system calls.
 
 config CC_OPTIMIZE_FOR_SIZE
-	bool "Optimize for size" if EMBEDDED
+	bool "Optimize for size"
 	default y if ARM || H8300
 	help
 	  Enabling this option will pass "-Os" instead of "-O2" to gcc

linux-2.6-proc-vmcore-needs-not-embedded.patch:
 Kconfig |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-proc-vmcore-needs-not-embedded.patch ---
--- linux-2.6.13/fs/Kconfig.orig	2005-08-28 19:41:01.000000000 -0400
+++ linux-2.6.13/fs/Kconfig	2005-09-01 15:12:01.784206308 -0400
@@ -755,7 +755,7 @@ config PROC_KCORE
 
 config PROC_VMCORE
         bool "/proc/vmcore support (EXPERIMENTAL)"
-        depends on PROC_FS && EMBEDDED && EXPERIMENTAL && CRASH_DUMP
+        depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP
         help
         Exports the dump image of crashed kernel in ELF format.
 

linux-2.6-procfs-i_nlink-miscalculate.patch:
 inode.c |    4 ----
 root.c  |   17 +++++++++--------
 2 files changed, 9 insertions(+), 12 deletions(-)

--- NEW FILE linux-2.6-procfs-i_nlink-miscalculate.patch ---
diff -urN linux-2.6.12/fs/proc/inode.c linux-2.6.12-fix/fs/proc/inode.c
--- linux-2.6.12/fs/proc/inode.c	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12-fix/fs/proc/inode.c	2005-07-28 06:55:40.000000000 -0400
@@ -199,10 +199,6 @@
 	root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
 	if (!root_inode)
 		goto out_no_root;
-	/*
-	 * Fixup the root inode's nlink value
-	 */
-	root_inode->i_nlink += nr_processes();
 	root_inode->i_uid = 0;
 	root_inode->i_gid = 0;
 	s->s_root = d_alloc_root(root_inode);
diff -urN linux-2.6.12/fs/proc/root.c linux-2.6.12-fix/fs/proc/root.c
--- linux-2.6.12/fs/proc/root.c	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12-fix/fs/proc/root.c	2005-07-28 06:54:51.000000000 -0400
@@ -79,16 +79,16 @@
 	proc_bus = proc_mkdir("bus", NULL);
 }
 
-static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
+)
 {
-	/*
-	 * nr_threads is actually protected by the tasklist_lock;
-	 * however, it's conventional to do reads, especially for
-	 * reporting, without any locking whatsoever.
-	 */
-	if (dir->i_ino == PROC_ROOT_INO) /* check for safety... */
-		dir->i_nlink = proc_root.nlink + nr_threads;
+	generic_fillattr(dentry->d_inode, stat);
+	stat->nlink = proc_root.nlink + nr_processes();
+	return 0;
+}
 
+static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+{
 	if (!proc_lookup(dir, dentry, nd)) {
 		return NULL;
 	}
@@ -133,6 +133,7 @@
  */
 static struct inode_operations proc_root_inode_operations = {
 	.lookup		= proc_root_lookup,
+	.getattr	= proc_root_getattr,
 };
 
 /*

linux-2.6-radeon-backlight.patch:
 radeon_base.c |   11 +
 radeon_pm.c   |  557 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 567 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-radeon-backlight.patch ---

http://bugme.osdl.org/show_bug.cgi?id=3022

--- vanilla/drivers/video/aty/radeon_pm.c	2005-10-27 20:02:08.000000000 -0400
+++ linux-2.6.14/drivers/video/aty/radeon_pm.c	2005-11-30 02:20:01.000000000 -0500
@@ -25,8 +25,532 @@
 #include <asm/pmac_feature.h>
 #endif
 
+/* For detecting supported PC laptops */
+#ifdef CONFIG_X86
+#include <linux/dmi.h>
+#endif
+
 #include "ati_ids.h"
 
+#ifdef CONFIG_X86
+/* This array holds a list of supported PC laptops.
+ * Currently only few IBM models are tested.
+ * If you want to experiment, use dmidecode to find out
+ * vendor and product codes for Your laptop.
+ */
+static struct dmi_system_id __devinitdata radeonfb_dmi_table[] = {
+
+	{
+		/* Reported by Stephan Groß <st.gross at inf.tu-dresden.de> */
+		.ident = "IBM ThinkPad T30 (2366-97G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "236697G"),
+		},
+	},
+	{
+		/* Reported by Phillip Jones <philljones at us.ibm.com> */
+		.ident = "IBM ThinkPad T30 (2366-MU9)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2366MU9"),
+		},
+	},
+	{
+		/* Reported by Jakob Schiotz <schiotz at fysik.dtu.dk> */
+		.ident = "IBM ThinkPad T30 (2366-96G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "236696G"),
+		},
+	},
+	{
+		/* Reported by Thomas M Steenholdt <tmus at tmus.dk> */
+		.ident = "IBM ThinkPad T30 (2366-JBG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2366JBG"),
+		},
+	},
+	{
+		/* Reported by ChazeFroy <chazefroy at gmail.com> */
+		.ident = "IBM ThinkPad T30 (2366-QU5)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2366QU5"),
+		},
+	},
+
+	{
+		/* Reported by George Avrunin <avrunin at math.umass.edu> */
+		.ident = "IBM ThinkPad T40 (2372-9CU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23729CU"),
+		},
+	},
+	{
+		/* Reported by Dmitriy Zavin <dzavin at yahoo.com> */
+		.ident = "IBM ThinkPad T40 (2373-14U)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237314U"),
+		},
+	},
+	{
+		/* Reported by Klaus Kurzmann <mok at fluxnetz.de> */
+		.ident = "IBM ThinkPad T40 (2373-25G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237325G"),
+		},
+	},
+	{
+		/* Reported by Antti P Miettinen <apm at brigitte.dna.fi> */
+		.ident = "IBM ThinkPad T40 (2373-4G2)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23734G2"),
+	      },
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad T40 (2373-92G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237392G"),
+	      },
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad T40 (2373-8CG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23738CG"),
+		},
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad T40 (2373-94U)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237394U"),
+		},
+	},
+	{
+		/* Reported by Manuel Carro <mcarro at fi.upm.es> */
+		.ident = "IBM ThinkPad T40 (2373-94G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237394G"),
+		},
+	},
+	{
+		/* Reported by Peter Jones <pjones at redhat.com> */
+		.ident = "IBM ThinkPad T40 (2373-BU7)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373BU7"),
+		},
+	},
+	{
+		/* Reported by Vernon Mauery <vernux at us.ibm.com> */
+		.ident = "IBM ThinkPad T40 (2373-MU4)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373MU4"),
+		},
+	},
+	{
+		/* Reported by Michele Lamarca <lammic at gmail.com> */
+		.ident = "IBM ThinkPad T40 (2373-22G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237322G"),
+		},
+	},
+	{
+		/* Reported by Adam Glasgall <adam at simons-rock.edu> */
+		.ident = "IBM ThinkPad T40 (2373-RU1)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373RU1"),
+		},
+	},
+	{
+		/* Reported by Juerg Billeter <j at bitron.ch> */
+		.ident = "IBM ThinkPad T40p (2373-G1G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373G1G"),
+		},
+	},
+	{
+		/* Reported by Bill Nottingham <notting at redhat.com> */
+		.ident = "IBM ThinkPad T40p (2373-G1U)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373G1U"),
+		},
+	},
+	{
+		/* Reported by Hartwig, Thomas <t.hartwig at itth.com> */
+		.ident = "IBM ThinkPad T40p (2373-G3G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373G3G"),
+		},
+	},
+
+	{
+		/* Reported by Antti Andreimann <Antti.Andreimann at mail.ee> */
+		.ident = "IBM ThinkPad T41 (2373-2FG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23732FG"),
+		},
+	},
+	{
+		/* Reported by Peter Jones <pjones at redhat.com> */
+		.ident = "IBM ThinkPad T41 (2373-9FU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23739FU"),
+		},
+	},
+	{
+		/* Reported by Ajay Ramaswamy <ajay at ramaswamy.net> */
+		.ident = "IBM ThinkPad T41 (2373-9HU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23739HU"),
+	      },
+	},
+	{
+		/* Reported by Ajay Ramaswamy <ajay at ramaswamy.net> */
+		.ident = "IBM ThinkPad T41 (2373-XNX)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373XNX"),
+	      },
+	},
+	{
+		/* Reported by obi <graziano at cs.ucsb.edu> */
+		.ident = "IBM ThinkPad T41 (2378-DEU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2378DEU"),
+		},
+	},
+	{
+		/* Reported by Volker Braun <vbraun at physics.upenn.edu> */
+		.ident = "IBM ThinkPad T41 (2379-DJU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2379DJU"),
+		},
+	},
+	{
+		/* Reported by Paul Ionescu <i_p_a_u_l at yahoo.com> */
+		.ident = "IBM ThinkPad T41 (2373-TG5)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373TG5"),
+		},
+	},
+	{
+		/* Reported by Matthew Saltzman <mjs at clemson.edu> */
+		.ident = "IBM ThinkPad T41 (2373-7JU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23737JU"),
+		},
+	},
+	{
+		/* Reported by David Zeuthen <davidz at redhat.com> */
+		.ident = "IBM ThinkPad T41 (2373-HU6)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373HU6"),
+		},
+	},
+	{
+		/* Reported by Grahame Bowland <grahame at angrygoats.net> */
+		.ident = "IBM ThinkPad T41 (2373-3HM)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23733HM"),
+		},
+	},
+	{
+		/* Reported by Aivo Prykk <aivo.prykk at mail.ee> */
+		.ident = "IBM ThinkPad T41 (2373-1FG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23731FG"),
+		},
+	},
+	{
+		/* Reported by Chris Vanden Berghe <Chris at VandenBerghe.org> */
+		.ident = "IBM ThinkPad T41 (2373-9HG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23739HG"),
+		},
+	},
+	{
+		/* Reported by Paul Stanisci <paul at stanisci.ca> */
+		.ident = "IBM ThinkPad T41 (2378-DLU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2378DLU"),
+		},
+	},
+	{
+		.ident = "IBM ThinkPad T41 (2379-D6U)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2379D6U"),
+		},
+	},
+
+	{
+		/* Reported by Eric Benson <eric_a_benson at yahoo.com> */
+		.ident = "IBM ThinkPad T41p (2373-GEU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373GEU"),
+		},
+	},
+
+	{
+		/* Reported by Tim Hull <thully at cyberspace.org> */
+		.ident = "IBM ThinkPad T42 (2374-6VU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23746VU"),
+		},
+	},
+	{
+		/* Reported by Dwight Barkley <barkley at maths.warwick.ac.uk> */
+		.ident = "IBM ThinkPad T42 (2373-JTU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373JTU"),
+		},
+	},
+	{
+		/* Reported by Jerome Poggi <Jerome.Poggi at hsc.fr>
+		  and Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad T42 (2373-FWG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373FWG"),
+		},
+	},
+	{
+		/* Reported by Ulrich Drepper <drepper at redhat.com> */
+		.ident = "IBM ThinkPad T42 (2378-R2U)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2378R2U"),
+		},
+	},
+	{
+		/* Reported by Nicolas Dufresne <nicolas.dufresne at usherbrooke.ca> */
+		.ident = "IBM ThinkPad T42 (2378-RBF)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2378RBF"),
+		},
+	},
+	{
+		/* Reported by Nicolas Dufresne <nicolas.dufresne at usherbrooke.ca> */
+		.ident = "IBM ThinkPad T42 (2378-RBU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2378RBU"),
+		},
+	},
+	{
+		/* Reported by Johannes Hansen */
+		.ident = "IBM ThinkPad T42 (2374-CTO)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2374CTO"),
+		},
+	},
+	{
+		/* Reported by Johannes Hansen */
+		.ident = "IBM ThinkPad T42 (2374-ZEP)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2374ZEP"),
+		},
+	},
+	{
+		/* Reported by Tom Marshall */
+		.ident = "IBM ThinkPad T42 (2378-XXE)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2378XXE"),
+		},
+	},
+	{
+		/* Reported by Isaac Wilcox */
+		.ident = "IBM ThinkPad T42 (2373-F2G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373F2G"),
+		},
+	},
+	{
+		/* Reported by Austin Clements <amdragon+osdlbugzilla at mit.edu> */
+		.ident = "IBM ThinkPad T42 (2378-DUU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2378DUU"),
+		},
+	},
+
+	{
+		/* Reported by Frank Otto <Frank.Otto at tc.pci.uni-heidelberg.de> */
+		.ident = "IBM ThinkPad R32 (2658-BQG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2658BQG"),
+		},
+	},
+
+	{
+		/* Reported by Frank Schmitt <tonne2004 at gehheimdienst.de> */
+		.ident = "IBM ThinkPad R40 (2722-3GG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "27223GG"),
+		},
+	},
+	{
+		/* Reported by Rushi Bhatt */
+		.ident = "IBM ThinkPad R40 (2722-6YU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "27226YU"),
+		},
+	},
+	{
+		/* Reported by Nils Trebing <nils.trebing at uni-konstanz.de> */
+		.ident = "IBM ThinkPad R40 (2722-5MG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "27225MG"),
+		},
+	},
+	{
+		/* Reported by Meik Hellmund <hellmund at math.uni-leipzig.de> */
+		.ident = "IBM ThinkPad R40 (2722-CDG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2722CDG"),
+		},
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad R40 (2722-B3G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2722B3G"),
+		},
+	},
+
+
+	{
+		/* Reported by Borschuk Oleg <merlinse at yandex.ru> */
+		.ident = "IBM ThinkPad R50 (1829-7RG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "18297RG"),
+		},
+	},
+
+	{
+		/* Reported by Georges Herber <gherber at gmail.com> */
+		.ident = "IBM ThinkPad R51 (1829-9MG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "18299MG"),
+		},
+	},
+	{
+		/* Reported by Eugene Pavlovsky */
+		.ident = "IBM ThinkPad R51 (1836-Q6U)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "1836Q6U"),
+		},
+	},
+	{
+		/* Reported by Sten Heinze */
+		.ident = "IBM ThinkPad R51 (1829-R6G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "1829R6G"),
+		},
+	},
+	{
+		/* Reported by Wouter Cloetens <wouter at mind.be> */
+		.ident = "IBM ThinkPad R51 (1829-EHG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "1829EHG"),
+		},
+	},
+
+
+	{
+		/* Reported by Henrik Brix Andersen <brix at gentoo.org> */
+		.ident = "IBM ThinkPad X31 (2672-XXH)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2672XXH"),
+		},
+	},
+	{
+		/* Reported by Jeremy Katz <katzj at redhat.com> */
+		.ident = "IBM ThinkPad X31 (2672-A9U)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2672A9U"),
+		},
+	},
+	{
+		/* Reported by Chris Lee <clee at redhat.com> */
+		.ident = "IBM ThinkPad X31 (2672-5KU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "26725KU"),
+		},
+	},
+	{
+		/* Reported by Chris Blizzard <blizzard at redhat.com> */
+		.ident = "IBM ThinkPad X31 (2672-RU3)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2672RU3"),
+		},
+	},
+	{ },
+	/* Negative reports: */
+	/* IBM thinkpad T42p 2373-KUU -> machine hangs as X starts
+	   Reported by: Dax Kelson <dax at gurulabs.com> */
+	/* IBM ThinkPad X31 2672-XXH -> works, but doesn't fix the LCD 
+	   backlight on during S3 issue.
+	   Reported by: Henrik Brix Andersen <brix at gentoo.org> */
+};
+
+extern int radeon_force_sleep;
+#endif
+
 static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
 {
 	u32 tmp;
@@ -852,7 +1376,14 @@ static void radeon_pm_setup_for_suspend(
 	/* because both INPLL and OUTPLL take the same lock, that's why. */
 	tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND;
 	OUTPLL( pllMCLK_MISC, tmp);
-	
+
+	/* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset
+	 * and radeon chip dependent. Thus we only enable it on Mac for
+	 * now (until we get more info on how to compute the correct
+	 * value for various X86 bridges).
+	 */
+
+#ifdef CONFIG_PPC_PMAC
 	/* AGP PLL control */
 	if (rinfo->family <= CHIP_FAMILY_RV280) {
 		OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
@@ -864,6 +1395,7 @@ static void radeon_pm_setup_for_suspend(
 		OUTREG(BUS_CNTL1, INREG(BUS_CNTL1));
 		OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000);
 	}
+#endif
 
 	OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL)
 				  & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
@@ -2779,6 +3311,29 @@ void radeonfb_pm_init(struct radeonfb_in
 #endif
 	}
 #endif /* defined(CONFIG_PM) && defined(CONFIG_PPC_OF) */
+
+/* The PM code also works on some PC laptops.
+ * Only a few models are actually tested so Your mileage may vary.
+ * We can do D2 on at least M7 and M9 on some IBM ThinkPad T41 models.
+ */
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+	if (radeon_force_sleep || dmi_check_system(radeonfb_dmi_table)) {
+		if (radeon_force_sleep)
+			printk("radeonfb: forcefully enabling sleep mode\n");
+		else
+			printk("radeonfb: enabling sleep mode\n");
+
+		if (rinfo->is_mobility && rinfo->pm_reg &&
+		    rinfo->family <= CHIP_FAMILY_RV250)
+			rinfo->pm_mode |= radeon_pm_d2;
+
+		/* Power down TV DAC, that saves a significant amount of power,
+		 * we'll have something better once we actually have some TVOut
+		 * support
+		 */
+		OUTREG(TV_DAC_CNTL, INREG(TV_DAC_CNTL) | 0x07000000);
+	}
+#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */
 }
 
 void radeonfb_pm_exit(struct radeonfb_info *rinfo)
--- vanilla/drivers/video/aty/radeon_base.c	2005-02-20 20:08:15.000000000 +0200
+++ linux-2.6.14/drivers/video/aty/radeon_base.c	2005-02-20 20:18:20.000000000 +0200
@@ -272,6 +272,9 @@
 #ifdef CONFIG_MTRR
 static int nomtrr = 0;
 #endif
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+int radeon_force_sleep = 0;
+#endif
 
 /*
  * prototypes
@@ -2530,6 +2533,10 @@
 			force_measure_pll = 1;
 		} else if (!strncmp(this_opt, "ignore_edid", 11)) {
 			ignore_edid = 1;
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+		} else if (!strncmp(this_opt, "force_sleep", 11)) {
+			radeon_force_sleep = 1;
+#endif
 		} else
 			mode_option = this_opt;
 	}
@@ -2585,3 +2592,7 @@
 MODULE_PARM_DESC(panel_yres, "int: set panel yres");
 module_param(mode_option, charp, 0);
 MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+module_param(radeon_force_sleep, int, 0);
+MODULE_PARM_DESC(radeon_force_sleep, "bool: force ACPI sleep mode on untested machines");
+#endif

linux-2.6-sata-enable-atapi-by-default.patch:
 libata-core.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-sata-enable-atapi-by-default.patch ---
--- linux-2.6.14/drivers/scsi/libata-core.c~	2005-11-22 11:33:25.000000000 -0500
+++ linux-2.6.14/drivers/scsi/libata-core.c	2005-11-22 11:33:37.000000000 -0500
@@ -78,7 +78,7 @@ static void __ata_qc_complete(struct ata
 static unsigned int ata_unique_id = 1;
 static struct workqueue_struct *ata_wq;
 
-int atapi_enabled = 0;
+int atapi_enabled = 1;
 module_param(atapi_enabled, int, 0444);
 MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
 

linux-2.6-scsi-advansys-enabler.patch:
 Kconfig |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-scsi-advansys-enabler.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1070/drivers/scsi/Kconfig linux-1101/drivers/scsi/Kconfig
--- linux-1070/drivers/scsi/Kconfig
+++ linux-1101/drivers/scsi/Kconfig
@@ -382,7 +382,7 @@ config SCSI_DPT_I2O
 
 config SCSI_ADVANSYS
 	tristate "AdvanSys SCSI support"
-	depends on (ISA || EISA || PCI) && SCSI && BROKEN
+	depends on (ISA || EISA || PCI) && SCSI
 	help
 	  This is a driver for all SCSI host adapters manufactured by
 	  AdvanSys. It is documented in the kernel source in

linux-2.6-scsi-advansys-pcitable.patch:
 drivers/scsi/advansys.c              |   82 +++++++++++++++++------------------
 linux-2.6.14/include/linux/pci_ids.h |    7 ++
 2 files changed, 48 insertions(+), 41 deletions(-)

--- NEW FILE linux-2.6-scsi-advansys-pcitable.patch ---
Remove a lot of duplicate #defines from the advansys driver.

--- linux-2.6.14/include/linux/pci_ids.h~	2005-10-30 21:36:21.000000000 -0500
+++ linux-2.6.14/include/linux/pci_ids.h	2005-10-30 21:37:16.000000000 -0500
@@ -949,6 +949,13 @@
 #define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
 #define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
 
+#define PCI_VENDOR_ID_ASP		0x10cd
+#define PCI_DEVICE_ID_ASP_1200A		0x1100
+#define PCI_DEVICE_ID_ASP_ABP940	0x1200
+#define PCI_DEVICE_ID_ASP_ABP940U	0x1300
+#define PCI_DEVICE_ID_ASP_ABP940UW	0x2300
+#define PCI_DEVICE_ID_38C0800_REV1	0x2500
+#define PCI_DEVICE_ID_38C1600_REV1	0x2700
 
 #define PCI_VENDOR_ID_TCONRAD		0x10da
 #define PCI_DEVICE_ID_TCONRAD_TOKENRING	0x0508
--- vanilla/drivers/scsi/advansys.c	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/drivers/scsi/advansys.c	2005-07-05 23:27:48.000000000 -0400
@@ -889,10 +889,6 @@ typedef unsigned char uchar;
 #define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
 #define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
-#define ASC_PCI_VENDORID                  0x10CD
-#define ASC_PCI_DEVICEID_1200A            0x1100
-#define ASC_PCI_DEVICEID_1200B            0x1200
-#define ASC_PCI_DEVICEID_ULTRA            0x1300
 #define ASC_PCI_REVISION_3150             0x02
 #define ASC_PCI_REVISION_3050             0x03
 
@@ -1493,8 +1489,6 @@ typedef struct asc_dvc_cfg {
 #define ASC_INIT_STATE_END_INQUIRY   0x0080
 #define ASC_INIT_RESET_SCSI_DONE     0x0100
 #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
-#define ASC_PCI_DEVICE_ID_REV_A      0x1100
-#define ASC_PCI_DEVICE_ID_REV_B      0x1200
 #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
@@ -2101,12 +2095,6 @@ STATIC ASC_DCNT  AscGetMaxDmaCount(ushor
 #define ADV_NUM_PAGE_CROSSING \
     ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
 
-/* a_condor.h */
-#define ADV_PCI_VENDOR_ID               0x10CD
-#define ADV_PCI_DEVICE_ID_REV_A         0x2300
-#define ADV_PCI_DEVID_38C0800_REV1      0x2500
-#define ADV_PCI_DEVID_38C1600_REV1      0x2700
-
 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
 #define ADV_EEP_DVC_CFG_END             (0x15)
 #define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
@@ -3570,14 +3558,7 @@ typedef struct scsi_cmnd     REQ, *REQP;
 #define PCI_MAX_SLOT            0x1F
 #define PCI_MAX_BUS             0xFF
 #define PCI_IOADDRESS_MASK      0xFFFE
-#define ASC_PCI_VENDORID        0x10CD
 #define ASC_PCI_DEVICE_ID_CNT   6       /* PCI Device ID count. */
-#define ASC_PCI_DEVICE_ID_1100  0x1100
-#define ASC_PCI_DEVICE_ID_1200  0x1200
-#define ASC_PCI_DEVICE_ID_1300  0x1300
-#define ASC_PCI_DEVICE_ID_2300  0x2300  /* ASC-3550 */
-#define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
-#define ASC_PCI_DEVICE_ID_2700  0x2700  /* ASC-38C1600 */
 
 #ifndef ADVANSYS_STATS
 #define ASC_STATS(shp, counter)
@@ -4331,12 +4312,12 @@ advansys_detect(struct scsi_host_templat
     struct pci_dev      *pci_devp = NULL;
     int                 pci_device_id_cnt = 0;
     unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
-                                    ASC_PCI_DEVICE_ID_1100,
-                                    ASC_PCI_DEVICE_ID_1200,
-                                    ASC_PCI_DEVICE_ID_1300,
-                                    ASC_PCI_DEVICE_ID_2300,
-                                    ASC_PCI_DEVICE_ID_2500,
-                                    ASC_PCI_DEVICE_ID_2700
+                                    PCI_DEVICE_ID_ASP_1200A,
+                                    PCI_DEVICE_ID_ASP_ABP940,
+                                    PCI_DEVICE_ID_ASP_ABP940U,
+                                    PCI_DEVICE_ID_ASP_ABP940UW,
+                                    PCI_DEVICE_ID_38C0800_REV1,
+                                    PCI_DEVICE_ID_38C1600_REV1
                         };
     ADV_PADDR           pci_memory_address;
 #endif /* CONFIG_PCI */
@@ -4472,7 +4453,7 @@ advansys_detect(struct scsi_host_templat
 
                     /* Find all PCI cards. */
                     while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
-                        if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
+                        if ((pci_devp = pci_find_device(PCI_VENDOR_ID_ASP,
                             pci_device_id[pci_device_id_cnt], pci_devp)) ==
                             NULL) {
                             pci_device_id_cnt++;
@@ -4578,9 +4559,9 @@ advansys_detect(struct scsi_host_templat
              */
 #ifdef CONFIG_PCI
             if (asc_bus[bus] == ASC_IS_PCI &&
-                (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
-                 pci_devp->device == ASC_PCI_DEVICE_ID_2500 ||
-                 pci_devp->device == ASC_PCI_DEVICE_ID_2700))
+                (pci_devp->device == PCI_DEVICE_ID_ASP_ABP940UW ||
+                 pci_devp->device == PCI_DEVICE_ID_38C0800_REV1 ||
+                 pci_devp->device == PCI_DEVICE_ID_38C1600_REV1))
             {
                 boardp->flags |= ASC_IS_WIDE_BOARD;
             }
@@ -4603,11 +4584,11 @@ advansys_detect(struct scsi_host_templat
                 adv_dvc_varp->isr_callback = adv_isr_callback;
                 adv_dvc_varp->async_callback = adv_async_callback;
 #ifdef CONFIG_PCI
-                if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
+                if (pci_devp->device == PCI_DEVICE_ID_ASP_ABP940UW)
                 {
                     ASC_DBG(1, "advansys_detect: ASC-3550\n");
                     adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
-                } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500)
+                } else if (pci_devp->device == PCI_DEVICE_ID_38C0800_REV1)
                 {
                     ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
                     adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
@@ -11929,7 +11910,7 @@ AscInitGetConfig(
         PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
                                     AscPCIConfigRevisionIDRegister);
 
-        if (PCIVendorID != ASC_PCI_VENDORID) {
+        if (PCIVendorID != PCI_VENDOR_ID_ASP) {
             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
         }
         prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
@@ -11949,15 +11930,15 @@ AscInitGetConfig(
                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
             }
         }
-        if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
-            (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
+        if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
+            (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
             DvcWritePCIConfigByte(asc_dvc,
                             AscPCIConfigLatencyTimer, 0x00);
             if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
                 != 0x00) {
                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
             }
-        } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
+        } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
             if (DvcReadPCIConfigByte(asc_dvc,
                                 AscPCIConfigLatencyTimer) < 0x20) {
                 DvcWritePCIConfigByte(asc_dvc,
@@ -12044,8 +12025,8 @@ AscInitFromAscDvcVar(
         AscSetChipCfgMsw(iop_base, cfg_msw);
         if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
         } else {
-            if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
-                (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
+            if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
+                (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
             }
@@ -14282,8 +14263,8 @@ Default_38C0800_EEPROM_Config __initdata
     0,                          /* 55 reserved */
     0,                          /* 56 cisptr_lsw */
     0,                          /* 57 cisprt_msw */
-    ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
-    ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */
+    PCI_VENDOR_ID_ASP,          /* 58 subsysvid */
+    PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
     0,                          /* 60 reserved */
     0,                          /* 61 reserved */
     0,                          /* 62 reserved */
@@ -14412,8 +14393,8 @@ Default_38C1600_EEPROM_Config __initdata
     0,                          /* 55 reserved */
     0,                          /* 56 cisptr_lsw */
     0,                          /* 57 cisprt_msw */
-    ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
-    ADV_PCI_DEVID_38C1600_REV1, /* 59 subsysid */
+    PCI_VENDOR_ID_ASP,          /* 58 subsysvid */
+    PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
     0,                          /* 60 reserved */
     0,                          /* 61 reserved */
     0,                          /* 62 reserved */




The advansys driver needs a lot of TLC. It does all its probing
for devices in a prehistoric way.  This patch at least allows
anaconda to recognise that the devices exist.

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=162431


--- vanilla/drivers/scsi/advansys.c	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/drivers/scsi/advansys.c	2005-07-05 23:27:48.000000000 -0400
@@ -18232,3 +18213,22 @@ AdvInquiryHandling(
     }
 }
 MODULE_LICENSE("Dual BSD/GPL");
+
+/* PCI Devices supported by this driver */
+static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
+

linux-2.6-scsi-megaraid-legacy.patch:
 linux-1102/drivers/scsi/megaraid/Kconfig.megaraid |    2 --
 linux-2.6.12/drivers/scsi/megaraid.c              |   12 +-----------
 linux-2.6.12/drivers/scsi/megaraid.h              |    4 ----
 3 files changed, 1 insertion(+), 17 deletions(-)

--- NEW FILE linux-2.6-scsi-megaraid-legacy.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1101/drivers/scsi/megaraid/Kconfig.megaraid linux-1102/drivers/scsi/megaraid/Kconfig.megaraid
--- linux-1101/drivers/scsi/megaraid/Kconfig.megaraid
+++ linux-1102/drivers/scsi/megaraid/Kconfig.megaraid
@@ -64,7 +64,6 @@ config MEGARAID_MAILBOX
 	To compile this driver as a module, choose M here: the
 	module will be called megaraid_mbox
 
-if MEGARAID_NEWGEN=n
 config MEGARAID_LEGACY
 	tristate "LSI Logic Legacy MegaRAID Driver"
 	depends on PCI && SCSI
@@ -74,7 +74,6 @@ config MEGARAID_LEGACY
 
 	To compile this driver as a module, choose M here: the
 	module will be called megaraid
-endif
 
 config MEGARAID_SAS
 	tristate "LSI Logic MegaRAID SAS RAID Module"
--- linux-2.6.12/drivers/scsi/megaraid.c~	2005-08-08 23:25:13.000000000 -0400
+++ linux-2.6.12/drivers/scsi/megaraid.c	2005-08-08 23:31:14.000000000 -0400
@@ -5014,22 +5014,12 @@ megaraid_shutdown(struct pci_dev *pdev)
 }
 
 static struct pci_device_id megaraid_pci_tbl[] = {
-	{PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DISCOVERY,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
-	{PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_QC_VERDE,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
--- linux-2.6.12/drivers/scsi/megaraid.h~	2005-08-08 23:26:41.000000000 -0400
+++ linux-2.6.12/drivers/scsi/megaraid.h	2005-08-08 23:33:14.000000000 -0400
@@ -73,10 +73,6 @@
 #define PCI_DEVICE_ID_AMI_MEGARAID3	0x1960
 #endif
 
-#define PCI_DEVICE_ID_DISCOVERY		0x000E
-#define PCI_DEVICE_ID_PERC4_DI		0x000F
-#define PCI_DEVICE_ID_PERC4_QC_VERDE	0x0407
-
 /* Sub-System Vendor IDs */
 #define	AMI_SUBSYS_VID			0x101E
 #define DELL_SUBSYS_VID			0x1028
--- linux-2.6.12/drivers/scsi/megaraid.c~	2005-08-08 23:33:34.000000000 -0400
+++ linux-2.6.12/drivers/scsi/megaraid.c	2005-08-08 23:33:52.000000000 -0400
@@ -5025,7 +5025,7 @@ static struct pci_device_id megaraid_pci
 MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
 
 static struct pci_driver megaraid_pci_driver = {
-	.name		= "megaraid",
+	.name		= "megaraid_legacy",
 	.id_table	= megaraid_pci_tbl,
 	.probe		= megaraid_probe_one,
 	.remove		= __devexit_p(megaraid_remove_one),

linux-2.6-selinux-hush.patch:
 nlmsgtab.c |    3 +++
 1 files changed, 3 insertions(+)

--- NEW FILE linux-2.6-selinux-hush.patch ---

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=167852

--- linux-2.6.13/security/selinux/nlmsgtab.c~	2005-09-30 06:45:08.000000000 -0400
+++ linux-2.6.13/security/selinux/nlmsgtab.c	2005-09-30 06:45:32.000000000 -0400
@@ -100,6 +100,9 @@ static struct nlmsg_perm nlmsg_audit_per
 	{ AUDIT_DEL,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
 	{ AUDIT_USER,		NETLINK_AUDIT_SOCKET__NLMSG_RELAY    },
 	{ AUDIT_SIGNAL_INFO,	NETLINK_AUDIT_SOCKET__NLMSG_READ     },
+	{ AUDIT_WATCH_INS,	NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
+	{ AUDIT_WATCH_REM,	NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
+	{ AUDIT_WATCH_LIST,	NETLINK_AUDIT_SOCKET__NLMSG_READPRIV },
 };
 
 

linux-2.6-serial-of.patch:
 linux-2.6.13/arch/powerpc/kernel/setup_64.c |  184 -------------------------
 linux-2.6.13/drivers/serial/8250_of.c       |  206 ++++++++++++++++++++++++++++
 linux-2.6.13/drivers/serial/Kconfig         |    5 
 linux-2.6.14/drivers/serial/Makefile        |    1 
 4 files changed, 212 insertions(+), 184 deletions(-)

--- NEW FILE linux-2.6-serial-of.patch ---
--- linux-2.6.14/drivers/serial/Makefile~	2005-11-07 22:17:27.000000000 -0500
+++ linux-2.6.14/drivers/serial/Makefile	2005-11-07 22:17:35.000000000 -0500
@@ -22,6 +22,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250
 obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
 obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+obj-$(CONFIG_SERIAL_8250_OF) += 8250_of.o
 obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
--- linux-2.6.13/drivers/serial/8250_of.c.sof	2005-10-20 13:19:07.000000000 +0100
+++ linux-2.6.13/drivers/serial/8250_of.c	2005-10-20 13:19:26.000000000 +0100
@@ -0,0 +1,206 @@
+/* 
+ * Search OpenFirmware device tree for 8250-compatible serial ports 
+ * 
+ * Moved from arch/powerpc/kernel/setup_64.c:
+ *
+ *	Copyright (C) 2001 PPC64, IBM Corp
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/serial.h>
+#include <asm/prom.h>
+
+/*
+ * This function can be used by platforms to "find" legacy serial ports.
+ * It works for "serial" nodes under an "isa" node, and will try to
+ * respect the "ibm,aix-loc" property if any. It works with up to 8
+ * ports.
+ */
+
+#define MAX_LEGACY_SERIAL_PORTS	8
+static int ports_probed = 0;
+
+static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
+static unsigned int old_serial_count;
+
+void __init generic_find_legacy_serial_ports(u64 *physport,
+		unsigned int *default_speed)
+{
+	struct device_node *np;
+	u32 *sizeprop;
+
+	struct isa_reg_property {
+		u32 space;
+		u32 address;
+		u32 size;
+	};
+
+	pr_debug(" -> generic_find_legacy_serial_port()\n");
+	ports_probed = 1;
+
+	*physport = 0;
+	if (default_speed)
+		*default_speed = 0;
+
+	np = of_find_node_by_path("/");
+	if (!np)
+		return;
+
+	/* First fill our array */
+	for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
+		struct device_node *isa, *pci;
+		struct isa_reg_property *reg;
+		unsigned long phys_size, addr_size;
+		u64 io_base;
+		u32 *rangesp;
+		u32 *interrupts, *clk, *spd;
+		char *typep;
+		int index, rlen, rentsize;
+
+		/* Ok, first check if it's under an "isa" parent */
+		isa = of_get_parent(np);
+		if (!isa || strcmp(isa->name, "isa")) {
+			pr_debug("%s: no isa parent found\n", np->full_name);
+			continue;
+		}
+
+		/* Now look for an "ibm,aix-loc" property that gives us ordering
+		 * if any...
+		 */
+	 	typep = (char *)get_property(np, "ibm,aix-loc", NULL);
+
+		/* Get the ISA port number */
+		reg = (struct isa_reg_property *)get_property(np, "reg", NULL);
+		if (reg == NULL)
+			goto next_port;
+		/* We assume the interrupt number isn't translated ... */
+		interrupts = (u32 *)get_property(np, "interrupts", NULL);
+		/* get clock freq. if present */
+		clk = (u32 *)get_property(np, "clock-frequency", NULL);
+		/* get default speed if present */
+		spd = (u32 *)get_property(np, "current-speed", NULL);
+		/* Default to locate at end of array */
+		index = old_serial_count; /* end of the array by default */
+
+		/* If we have a location index, then use it */
+		if (typep && *typep == 'S') {
+			index = simple_strtol(typep+1, NULL, 0) - 1;
+			/* if index is out of range, use end of array instead */
+			if (index >= MAX_LEGACY_SERIAL_PORTS)
+				index = old_serial_count;
+			/* if our index is still out of range, that mean that
+			 * array is full, we could scan for a free slot but that
+			 * make little sense to bother, just skip the port
+			 */
+			if (index >= MAX_LEGACY_SERIAL_PORTS)
+				goto next_port;
+			if (index >= old_serial_count)
+				old_serial_count = index + 1;
+			/* Check if there is a port who already claimed our slot */
+			if (serial_ports[index].iobase != 0) {
+				/* if we still have some room, move it, else override */
+				if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
+					pr_debug("Moved legacy port %d -> %d\n", index,
+					    old_serial_count);
+					serial_ports[old_serial_count++] =
+						serial_ports[index];
+				} else {
+					pr_debug("Replacing legacy port %d\n", index);
+				}
+			}
+		}
+		if (index >= MAX_LEGACY_SERIAL_PORTS)
+			goto next_port;
+		if (index >= old_serial_count)
+			old_serial_count = index + 1;
+
+		/* Now fill the entry */
+		memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
+		serial_ports[index].uartclk = (clk && *clk) ? *clk : BASE_BAUD * 16;
+		serial_ports[index].iobase = reg->address;
+		serial_ports[index].irq = interrupts ? interrupts[0] : 0;
+		serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
+
+		pr_debug("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
+		    index,
+		    serial_ports[index].iobase,
+		    serial_ports[index].irq,
+		    serial_ports[index].uartclk);
+
+		/* Get phys address of IO reg for port 1 */
+		if (index != 0)
+			goto next_port;
+
+		pci = of_get_parent(isa);
+		if (!pci) {
+			pr_debug("%s: no pci parent found\n", np->full_name);
+			goto next_port;
+		}
+
+		rangesp = (u32 *)get_property(pci, "ranges", &rlen);
+		if (rangesp == NULL) {
+			of_node_put(pci);
+			goto next_port;
+		}
+		rlen /= 4;
+
+		/* we need the #size-cells of the PCI bridge node itself */
+		phys_size = 1;
+		sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
+		if (sizeprop != NULL)
+			phys_size = *sizeprop;
+		/* we need the parent #addr-cells */
+		addr_size = prom_n_addr_cells(pci);
+		rentsize = 3 + addr_size + phys_size;
+		io_base = 0;
+		for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
+			if (((rangesp[0] >> 24) & 0x3) != 1)
+				continue; /* not IO space */
+			io_base = rangesp[3];
+			if (addr_size == 2)
+				io_base = (io_base << 32) | rangesp[4];
+		}
+		if (io_base != 0) {
+			*physport = io_base + reg->address;
+			if (default_speed && spd)
+				*default_speed = *spd;
+		}
+		of_node_put(pci);
+	next_port:
+		of_node_put(isa);
+	}
+
+	pr_debug(" <- generic_find_legacy_serial_port()\n");
+}
+
+static struct platform_device serial_device = {
+	.name	= "serial8250",
+	.id	= PLAT8250_DEV_PLATFORM,
+	.dev	= {
+		.platform_data = serial_ports,
+	},
+};
+
+static int __init serial_dev_init(void)
+{
+	u64 phys;
+	unsigned int spd;
+
+	if (!ports_probed)
+		generic_find_legacy_serial_ports(&phys, &spd);
+	return platform_device_register(&serial_device);
+}
+arch_initcall(serial_dev_init);
--- linux-2.6.13/drivers/serial/Kconfig.sof	2005-10-20 12:54:48.000000000 +0100
+++ linux-2.6.13/drivers/serial/Kconfig	2005-10-20 13:05:39.000000000 +0100
@@ -77,6 +77,11 @@ config SERIAL_8250_CS
 
 	  If unsure, say N.
 
+config SERIAL_8250_OF
+       bool
+       default y
+       depends on PPC_OF && SERIAL_8250 && PPC_MERGE
+
 config SERIAL_8250_ACPI
 	bool "8250/16550 device discovery via ACPI namespace"
 	default y if IA64
--- linux-2.6.13/arch/powerpc/kernel/setup_64.c.sof	2005-10-20 13:13:08.000000000 +0100
+++ linux-2.6.13/arch/powerpc/kernel/setup_64.c	2005-10-20 13:16:28.000000000 +0100
@@ -31,8 +31,6 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/unistd.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
@@ -52,7 +50,6 @@
 #include <asm/system.h>
 #include <asm/rtas.h>
 #include <asm/iommu.h>
-#include <asm/serial.h>
 #include <asm/cache.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
@@ -1104,187 +1101,6 @@ void __init setup_default_decr(void)
 	lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
 }
 
-#ifndef CONFIG_PPC_ISERIES
-/*
- * This function can be used by platforms to "find" legacy serial ports.
- * It works for "serial" nodes under an "isa" node, and will try to
- * respect the "ibm,aix-loc" property if any. It works with up to 8
- * ports.
- */
-
-#define MAX_LEGACY_SERIAL_PORTS	8
-static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
-static unsigned int old_serial_count;
-
-void __init generic_find_legacy_serial_ports(u64 *physport,
-		unsigned int *default_speed)
-{
-	struct device_node *np;
-	u32 *sizeprop;
-
-	struct isa_reg_property {
-		u32 space;
-		u32 address;
-		u32 size;
-	};
-	struct pci_reg_property {
-		struct pci_address addr;
-		u32 size_hi;
-		u32 size_lo;
-	};                                                                        
-
-	DBG(" -> generic_find_legacy_serial_port()\n");
-
-	*physport = 0;
-	if (default_speed)
-		*default_speed = 0;
-
-	np = of_find_node_by_path("/");
-	if (!np)
-		return;
-
-	/* First fill our array */
-	for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
-		struct device_node *isa, *pci;
-		struct isa_reg_property *reg;
-		unsigned long phys_size, addr_size, io_base;
-		u32 *rangesp;
-		u32 *interrupts, *clk, *spd;
-		char *typep;
-		int index, rlen, rentsize;
-
-		/* Ok, first check if it's under an "isa" parent */
-		isa = of_get_parent(np);
-		if (!isa || strcmp(isa->name, "isa")) {
-			DBG("%s: no isa parent found\n", np->full_name);
-			continue;
-		}
-		
-		/* Now look for an "ibm,aix-loc" property that gives us ordering
-		 * if any...
-		 */
-	 	typep = (char *)get_property(np, "ibm,aix-loc", NULL);
-
-		/* Get the ISA port number */
-		reg = (struct isa_reg_property *)get_property(np, "reg", NULL);	
-		if (reg == NULL)
-			goto next_port;
-		/* We assume the interrupt number isn't translated ... */
-		interrupts = (u32 *)get_property(np, "interrupts", NULL);
-		/* get clock freq. if present */
-		clk = (u32 *)get_property(np, "clock-frequency", NULL);
-		/* get default speed if present */
-		spd = (u32 *)get_property(np, "current-speed", NULL);
-		/* Default to locate at end of array */
-		index = old_serial_count; /* end of the array by default */
-
-		/* If we have a location index, then use it */
-		if (typep && *typep == 'S') {
-			index = simple_strtol(typep+1, NULL, 0) - 1;
-			/* if index is out of range, use end of array instead */
-			if (index >= MAX_LEGACY_SERIAL_PORTS)
-				index = old_serial_count;
-			/* if our index is still out of range, that mean that
-			 * array is full, we could scan for a free slot but that
-			 * make little sense to bother, just skip the port
-			 */
-			if (index >= MAX_LEGACY_SERIAL_PORTS)
-				goto next_port;
-			if (index >= old_serial_count)
-				old_serial_count = index + 1;
-			/* Check if there is a port who already claimed our slot */
-			if (serial_ports[index].iobase != 0) {
-				/* if we still have some room, move it, else override */
-				if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
-					DBG("Moved legacy port %d -> %d\n", index,
-					    old_serial_count);
-					serial_ports[old_serial_count++] =
-						serial_ports[index];
-				} else {
-					DBG("Replacing legacy port %d\n", index);
-				}
-			}
-		}
-		if (index >= MAX_LEGACY_SERIAL_PORTS)
-			goto next_port;
-		if (index >= old_serial_count)
-			old_serial_count = index + 1;
-
-		/* Now fill the entry */
-		memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
-		serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16;
-		serial_ports[index].iobase = reg->address;
-		serial_ports[index].irq = interrupts ? interrupts[0] : 0;
-		serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
-
-		DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
-		    index,
-		    serial_ports[index].iobase,
-		    serial_ports[index].irq,
-		    serial_ports[index].uartclk);
-
-		/* Get phys address of IO reg for port 1 */
-		if (index != 0)
-			goto next_port;
-
-		pci = of_get_parent(isa);
-		if (!pci) {
-			DBG("%s: no pci parent found\n", np->full_name);
-			goto next_port;
-		}
-
-		rangesp = (u32 *)get_property(pci, "ranges", &rlen);
-		if (rangesp == NULL) {
-			of_node_put(pci);
-			goto next_port;
-		}
-		rlen /= 4;
-
-		/* we need the #size-cells of the PCI bridge node itself */
-		phys_size = 1;
-		sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
-		if (sizeprop != NULL)
-			phys_size = *sizeprop;
-		/* we need the parent #addr-cells */
-		addr_size = prom_n_addr_cells(pci);
-		rentsize = 3 + addr_size + phys_size;
-		io_base = 0;
-		for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
-			if (((rangesp[0] >> 24) & 0x3) != 1)
-				continue; /* not IO space */
-			io_base = rangesp[3];
-			if (addr_size == 2)
-				io_base = (io_base << 32) | rangesp[4];
-		}
-		if (io_base != 0) {
-			*physport = io_base + reg->address;
-			if (default_speed && spd)
-				*default_speed = *spd;
-		}
-		of_node_put(pci);
-	next_port:
-		of_node_put(isa);
-	}
-
-	DBG(" <- generic_find_legacy_serial_port()\n");
-}
-
-static struct platform_device serial_device = {
-	.name	= "serial8250",
-	.id	= PLAT8250_DEV_PLATFORM,
-	.dev	= {
-		.platform_data = serial_ports,
-	},
-};
-
-static int __init serial_dev_init(void)
-{
-	return platform_device_register(&serial_device);
-}
-arch_initcall(serial_dev_init);
-
-#endif /* CONFIG_PPC_ISERIES */
-
 int check_legacy_ioport(unsigned long base_port)
 {
 	if (ppc_md.check_legacy_ioport == NULL)

linux-2.6-serial-tickle-nmi.patch:
 8250.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-serial-tickle-nmi.patch ---

NMI Watchdog detected LOCKUP on CPU2CPU 2
Modules linked in: loop usb_storage md5 ipv6 parport_pc lp parport autofs4 i2c_dev i2c_core rfcomm l2cap bluetooth sunrpc pcdPid: 3138, comm: gpm Not tainted 2.6.11-1.1290_FC4smp
RIP: 0010:[<ffffffff80273b8a>] <ffffffff80273b8a>{serial_in+106}
RSP: 0018:ffff81003afc3d50  EFLAGS: 00000002
RAX: 0000000000000020 RBX: 0000000000000020 RCX: 0000000000000000
RDX: 00000000000003fd RSI: 0000000000000005 RDI: ffffffff804dcd60
RBP: 00000000000024fc R08: 000000000000000a R09: 0000000000000033
R10: ffff81001beb7c20 R11: 0000000000000020 R12: ffffffff804dcd60
R13: ffffffff804ade76 R14: 000000000000002b R15: 000000000000002c
FS:  00002aaaaaac4920(0000) GS:ffffffff804fca00(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00002aaaaabcb000 CR3: 000000003c0d0000 CR4: 00000000000006e0
Process gpm (pid: 3138, threadinfo ffff81003afc2000, task ffff81003eb63780)
Stack: ffffffff80275f2e 0000000000000000 ffffffff80448380 0000000000007d6b
       000000000000002c fffffffffffffbbf 0000000000000292 0000000000008000
       ffffffff80138e8c 0000000000007d97
Call Trace:<ffffffff80275f2e>{serial8250_console_write+270} <ffffffff80138e8c>{__call_console_drivers+76}
       <ffffffff8013914b>{release_console_sem+315} <ffffffff80260325>{con_open+149}
       <ffffffff80254e99>{tty_open+537} <ffffffff80192713>{chrdev_open+387}
       <ffffffff80188824>{dentry_open+260} <ffffffff80188994>{filp_open+68}
       <ffffffff80187b73>{get_unused_fd+227} <ffffffff80188a6c>{sys_open+76}
       <ffffffff8010ebc6>{tracesys+209}

Code: 0f b6 c0 c3 66 90 41 57 49 89 f7 41 56 41 be 00 01 00 00 41
console shuts up ...


--- linux-2.6.11/drivers/serial/8250.c~	2005-05-14 02:49:02.000000000 -0400
+++ linux-2.6.11/drivers/serial/8250.c	2005-05-14 02:54:30.000000000 -0400
@@ -2098,9 +2098,11 @@ static inline void wait_for_xmitr(struct
 	/* Wait up to 1s for flow control if necessary */
 	if (up->port.flags & UPF_CONS_FLOW) {
 		tmout = 1000000;
-		while (--tmout &&
-		       ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+		while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
 			udelay(1);
+			if ((tmout % 1000) == 0)
+				touch_nmi_watchdog();
+		}
 	}
 }
 

linux-2.6-sleepon.patch:
 drivers/block/DAC960.c        |   12 +++++++++++-
 drivers/net/tokenring/ibmtr.c |    9 ++++++++-
 include/linux/wait.h          |    6 +++---
 kernel/sched.c                |   28 +++++++++++++++-------------
 net/sunrpc/clnt.c             |    9 ++++++++-
 5 files changed, 45 insertions(+), 19 deletions(-)

--- NEW FILE linux-2.6-sleepon.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1060/drivers/block/DAC960.c linux-1070/drivers/block/DAC960.c
--- linux-1060/drivers/block/DAC960.c
+++ linux-1070/drivers/block/DAC960.c
@@ -6132,6 +6132,9 @@ static boolean DAC960_V2_ExecuteUserComm
   unsigned long flags;
   unsigned char Channel, TargetID, LogicalDriveNumber;
   unsigned short LogicalDeviceNumber;
+  wait_queue_t __wait;
+  
+  init_waitqueue_entry(&__wait, current);
 
   spin_lock_irqsave(&Controller->queue_lock, flags);
   while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
@@ -6314,11 +6317,18 @@ static boolean DAC960_V2_ExecuteUserComm
 					.SegmentByteCount =
 	    CommandMailbox->ControllerInfo.DataTransferSize;
 	  DAC960_ExecuteCommand(Command);
+	  add_wait_queue(&Controller->CommandWaitQueue, &__wait);
+	  set_current_state(TASK_UNINTERRUPTIBLE);
+	  
 	  while (Controller->V2.NewControllerInformation->PhysicalScanActive)
 	    {
 	      DAC960_ExecuteCommand(Command);
-	      sleep_on_timeout(&Controller->CommandWaitQueue, HZ);
+	      schedule_timeout(HZ);
+	      set_current_state(TASK_UNINTERRUPTIBLE);
 	    }
+	  current->state = TASK_RUNNING;
+	  remove_wait_queue(&Controller->CommandWaitQueue, &__wait);
+	   
 	  DAC960_UserCritical("Discovery Completed\n", Controller);
  	}
     }
diff -urNp --exclude-from=/home/davej/.exclude linux-1060/drivers/net/tokenring/ibmtr.c linux-1070/drivers/net/tokenring/ibmtr.c
--- linux-1060/drivers/net/tokenring/ibmtr.c
+++ linux-1070/drivers/net/tokenring/ibmtr.c
@@ -850,6 +850,8 @@ static int tok_init_card(struct net_devi
 	struct tok_info *ti;
 	short PIOaddr;
 	unsigned long i;
+	wait_queue_t __wait;
+	init_waitqueue_entry(&__wait, current);
 
 	PIOaddr = dev->base_addr;
 	ti = (struct tok_info *) dev->priv;
@@ -862,13 +864,18 @@ static int tok_init_card(struct net_devi
 	current->state=TASK_UNINTERRUPTIBLE;
 	schedule_timeout(TR_RST_TIME); /* wait 50ms */
 
+	add_wait_queue(&ti->wait_for_reset, &__wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
 	outb(0, PIOaddr + ADAPTRESETREL);
 #ifdef ENABLE_PAGING
 	if (ti->page_mask)
 		writeb(SRPR_ENABLE_PAGING,ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN);
 #endif
 	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-	i = sleep_on_timeout(&ti->wait_for_reset, 4 * HZ);
+	#warning pci posting bug
+	i = schedule_timeout(4 * HZ);
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&ti->wait_for_reset, &__wait);
 	return i? 0 : -EAGAIN;
 }
 
diff -urNp --exclude-from=/home/davej/.exclude linux-1060/include/linux/wait.h linux-1070/include/linux/wait.h
--- linux-1060/include/linux/wait.h
+++ linux-1070/include/linux/wait.h
@@ -364,10 +364,10 @@ static inline void remove_wait_queue_loc
  * They are racy.  DO NOT use them, use the wait_event* interfaces above.  
  * We plan to remove these interfaces during 2.7.
  */
-extern void FASTCALL(sleep_on(wait_queue_head_t *q));
-extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
+extern void __deprecated FASTCALL(sleep_on(wait_queue_head_t *q));
+extern long __deprecated FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
 				      signed long timeout));
-extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
+extern void __deprecated FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
 extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
 						    signed long timeout));
 
diff -urNp --exclude-from=/home/davej/.exclude linux-1060/kernel/sched.c linux-1070/kernel/sched.c
--- linux-1060/kernel/sched.c
+++ linux-1070/kernel/sched.c
@@ -3118,10 +3118,21 @@ EXPORT_SYMBOL(wait_for_completion_interr
 	__remove_wait_queue(q, &wait);			\
 	spin_unlock_irqrestore(&q->lock, flags);
 
+#define SLEEP_ON_BKLCHECK				\
+	if (unlikely(!kernel_locked()) &&		\
+	    sleep_on_bkl_warnings < 10) {		\
+		sleep_on_bkl_warnings++;		\
+		WARN_ON(1);				\
+	}
+
+static int sleep_on_bkl_warnings;
+
 void fastcall __sched interruptible_sleep_on(wait_queue_head_t *q)
 {
 	SLEEP_ON_VAR
 
+	SLEEP_ON_BKLCHECK
+
 	current->state = TASK_INTERRUPTIBLE;
 
 	SLEEP_ON_HEAD
@@ -3135,6 +3146,8 @@ long fastcall __sched interruptible_slee
 {
 	SLEEP_ON_VAR
 
+	SLEEP_ON_BKLCHECK
+
 	current->state = TASK_INTERRUPTIBLE;
 
 	SLEEP_ON_HEAD
@@ -3146,23 +3159,12 @@ long fastcall __sched interruptible_slee
 
 EXPORT_SYMBOL(interruptible_sleep_on_timeout);
 
-void fastcall __sched sleep_on(wait_queue_head_t *q)
-{
-	SLEEP_ON_VAR
-
-	current->state = TASK_UNINTERRUPTIBLE;
-
-	SLEEP_ON_HEAD
-	schedule();
-	SLEEP_ON_TAIL
-}
-
-EXPORT_SYMBOL(sleep_on);
-
 long fastcall __sched sleep_on_timeout(wait_queue_head_t *q, long timeout)
 {
 	SLEEP_ON_VAR
 
+	SLEEP_ON_BKLCHECK
+
 	current->state = TASK_UNINTERRUPTIBLE;
 
 	SLEEP_ON_HEAD
diff -urNp --exclude-from=/home/davej/.exclude linux-1060/net/sunrpc/clnt.c linux-1070/net/sunrpc/clnt.c
--- linux-1060/net/sunrpc/clnt.c
+++ linux-1070/net/sunrpc/clnt.c
@@ -223,17 +223,24 @@ out_no_clnt:
 int
 rpc_shutdown_client(struct rpc_clnt *clnt)
 {
+	wait_queue_t __wait;
+	init_waitqueue_entry(&__wait, current);
 	dprintk("RPC: shutting down %s client for %s, tasks=%d\n",
 			clnt->cl_protname, clnt->cl_server,
 			atomic_read(&clnt->cl_users));
 
+	add_wait_queue(&destroy_wait, &__wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
 	while (atomic_read(&clnt->cl_users) > 0) {
 		/* Don't let rpc_release_client destroy us */
 		clnt->cl_oneshot = 0;
 		clnt->cl_dead = 0;
 		rpc_killall_tasks(clnt);
-		sleep_on_timeout(&destroy_wait, 1*HZ);
+		schedule_timeout(1*HZ);
+		set_current_state(TASK_UNINTERRUPTIBLE);
 	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&destroy_wait, &__wait);
 
 	if (atomic_read(&clnt->cl_users) < 0) {
 		printk(KERN_ERR "RPC: rpc_shutdown_client clnt %p tasks=%d\n",

linux-2.6-sound-emu10k1-ac97.patch:
 emu10k1_main.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6-sound-emu10k1-ac97.patch ---
--- linux-2.6.13/sound/pci/emu10k1/emu10k1_main.c~	2005-10-03 20:55:51.000000000 -0400
+++ linux-2.6.13/sound/pci/emu10k1/emu10k1_main.c	2005-10-03 20:56:04.000000000 -0400
@@ -759,6 +759,7 @@ static emu_chip_details_t emu_chip_detai
 	 .driver = "EMU10K1", .name = "SBLive! Platinum 5.1 [SB0060]", 
 	 .id = "Live",
 	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
 	 .sblive51 = 1} ,
 	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
 	 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", 

linux-2.6-squashfs.patch:
 fs/Kconfig                     |   63 +
 fs/Makefile                    |    1 
 fs/squashfs/Makefile           |    7 
 fs/squashfs/inode.c            | 1803 +++++++++++++++++++++++++++++++++++++++++
 include/linux/squashfs_fs.h    |  519 +++++++++++
 include/linux/squashfs_fs_i.h  |   43 
 include/linux/squashfs_fs_sb.h |   65 +
 7 files changed, 2501 insertions(+)

--- NEW FILE linux-2.6-squashfs.patch ---
diff --new-file -urp linux-2.6.13/fs/Kconfig linux-2.6.13-squashfs2.2-r2/fs/Kconfig
--- linux-2.6.13/fs/Kconfig	2005-08-29 00:41:01.000000000 +0100
+++ linux-2.6.13-squashfs2.2-r2/fs/Kconfig	2005-09-09 00:40:06.000000000 +0100
@@ -1155,6 +1155,69 @@ config CRAMFS
 
 	  If unsure, say N.
 
+config SQUASHFS
+	tristate "SquashFS 2.2 - Squashed file system support"
+	select ZLIB_INFLATE
+	help
+	  Saying Y here includes support for SquashFS 2.2 (Compressed Read-Only File
+	  System).  Squashfs is a highly compressed read-only filesystem for Linux.
+	  It uses zlib compression to compress both files, inodes and directories.
+	  Inodes in the system are very small and all blocks are packed to minimise
+	  data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.
+
+	  Squashfs is intended for general read-only filesystem use, for archival
+	  use (i.e. in cases where a .tar.gz file may be used), and in embedded
+	  systems where low overhead is needed.  Further information and filesystem tools
+	  are available from http://squashfs.sourceforge.net.
+
+	  If you want to compile this as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want),
+	  say M here and read <file:Documentation/modules.txt>.  The module
+	  will be called squashfs.  Note that the root file system (the one
+	  containing the directory /) cannot be compiled as a module.
+
+	  If unsure, say N.
+
+config SQUASHFS_EMBEDDED
+
+	bool "Additional options for memory-constrained systems" 
+	depends on SQUASHFS
+	default n
+	help
+	  Saying Y here allows you to specify cache sizes and how Squashfs
+	  allocates memory.  This is only intended for memory constrained
+	  systems.
+
+	  If unsure, say N.
+
+config SQUASHFS_FRAGMENT_CACHE_SIZE
+	int "Number of fragments cached" if SQUASHFS_EMBEDDED
+	depends on SQUASHFS
+	default "3"
+	help
+	  By default SquashFS caches the last 3 fragments read from
+	  the filesystem.  Increasing this amount may mean SquashFS
+	  has to re-read fragments less often from disk, at the expense
+	  of extra system memory.  Decreasing this amount will mean
+	  SquashFS uses less memory at the expense of extra reads from disk.
+
+	  Note there must be at least one cached fragment.  Anything
+	  much more than three will probably not make much difference.
+
+config SQUASHFS_VMALLOC
+	bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED
+	depends on SQUASHFS
+	default n
+	help
+	  By default SquashFS uses kmalloc to obtain fragment cache memory.
+	  Kmalloc memory is the standard kernel allocator, but it can fail
+	  on memory constrained systems.  Because of the way Vmalloc works,
+	  Vmalloc can succeed when kmalloc fails.  Specifying this option
+	  will make SquashFS always use Vmalloc to allocate the
+	  fragment cache memory.
+
+	  If unsure, say N.
+
 config VXFS_FS
 	tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
 	help
diff --new-file -urp linux-2.6.13/fs/Makefile linux-2.6.13-squashfs2.2-r2/fs/Makefile
--- linux-2.6.13/fs/Makefile	2005-08-29 00:41:01.000000000 +0100
+++ linux-2.6.13-squashfs2.2-r2/fs/Makefile	2005-09-09 00:39:17.000000000 +0100
@@ -55,6 +55,7 @@ obj-$(CONFIG_EXT3_FS)		+= ext3/ # Before
 obj-$(CONFIG_JBD)		+= jbd/
 obj-$(CONFIG_EXT2_FS)		+= ext2/
 obj-$(CONFIG_CRAMFS)		+= cramfs/
+obj-$(CONFIG_SQUASHFS)		+= squashfs/
 obj-$(CONFIG_RAMFS)		+= ramfs/
 obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
 obj-$(CONFIG_CODA_FS)		+= coda/
diff --new-file -urp linux-2.6.13/fs/squashfs/inode.c linux-2.6.13-squashfs2.2-r2/fs/squashfs/inode.c
--- linux-2.6.13/fs/squashfs/inode.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.13-squashfs2.2-r2/fs/squashfs/inode.c	2005-09-09 00:40:54.000000000 +0100
@@ -0,0 +1,1803 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005 Phillip Lougher <phillip at lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * inode.c
+ */
+
+#define SQUASHFS_1_0_COMPATIBILITY
+
+#include <linux/types.h>
+#include <linux/squashfs_fs.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/squashfs_fs_sb.h>
+#include <linux/squashfs_fs_i.h>
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include <linux/init.h>
+#include <linux/dcache.h>
+#include <asm/uaccess.h>
+#include <linux/wait.h>
+#include <asm/semaphore.h>
+#include <linux/zlib.h>
+#include <linux/blkdev.h>
+#include <linux/vmalloc.h>
+
+#ifdef SQUASHFS_TRACE
+#define TRACE(s, args...)				printk(KERN_NOTICE "SQUASHFS: "s, ## args)
+#else
+#define TRACE(s, args...)				{}
+#endif
+
+#define ERROR(s, args...)				printk(KERN_ERR "SQUASHFS error: "s, ## args)
+
+#define SERROR(s, args...)				if(!silent) printk(KERN_ERR "SQUASHFS error: "s, ## args)
+#define WARNING(s, args...)				printk(KERN_WARNING "SQUASHFS: "s, ## args)
+
+static void squashfs_put_super(struct super_block *);
+static int squashfs_statfs(struct super_block *, struct kstatfs *);
+static int squashfs_symlink_readpage(struct file *file, struct page *page);
+static int squashfs_readpage(struct file *file, struct page *page);
+static int squashfs_readpage4K(struct file *file, struct page *page);
+static int squashfs_readdir(struct file *, void *, filldir_t);
+static struct dentry *squashfs_lookup(struct inode *, struct dentry *, struct nameidata *);
+static unsigned int read_data(struct super_block *s, char *buffer,
+		unsigned int index, unsigned int length, unsigned int *next_index);
+static int squashfs_get_cached_block(struct super_block *s, char *buffer,
+		unsigned int block, unsigned int offset, int length,
+		unsigned int *next_block, unsigned int *next_offset);
+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode inode);
+static unsigned int read_blocklist(struct inode *inode, int index, int readahead_blks,
+		char *block_list, unsigned short **block_p, unsigned int *bsize);
+static void squashfs_put_super(struct super_block *s);
+static struct super_block *squashfs_get_sb(struct file_system_type *, int, const char *, void *);
+static struct inode *squashfs_alloc_inode(struct super_block *sb);
+static void squashfs_destroy_inode(struct inode *inode);
+static int init_inodecache(void);
+static void destroy_inodecache(void);
+
+#ifdef SQUASHFS_1_0_COMPATIBILITY
+static int squashfs_readpage_lessthan4K(struct file *file, struct page *page);
+static struct inode *squashfs_iget_1(struct super_block *s, squashfs_inode inode);
+static unsigned int read_blocklist_1(struct inode *inode, int index, int readahead_blks,
+		char *block_list, unsigned short **block_p, unsigned int *bsize);
+#endif
+
+DECLARE_MUTEX(read_data_mutex);
+
+static z_stream stream;
+
+static struct file_system_type squashfs_fs_type = {
+	.owner = THIS_MODULE,
+	.name = "squashfs",
+	.get_sb = squashfs_get_sb,
+	.kill_sb = kill_block_super,
+	.fs_flags = FS_REQUIRES_DEV
+	};
+
+static unsigned char squashfs_filetype_table[] = {
+	DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
+};
+
+static struct super_operations squashfs_ops = {
+	.alloc_inode = squashfs_alloc_inode,
+	.destroy_inode = squashfs_destroy_inode,
+	.statfs = squashfs_statfs,
+	.put_super = squashfs_put_super,
+};
+
+static struct address_space_operations squashfs_symlink_aops = {
+	.readpage = squashfs_symlink_readpage
+};
[...2142 lines suppressed...]
+	unsigned int		mtime;
+	squashfs_block		start_block;
+	unsigned int		file_size:SQUASHFS_MAX_FILE_SIZE_LOG;
+	unsigned short		block_list[0];
+} __attribute__ ((packed)) squashfs_reg_inode_header_1;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:4; /* index into uid table */
+	unsigned int		guid:4; /* index into guid table */
+	unsigned int		file_size:19;
+	unsigned int		offset:13;
+	unsigned int		mtime;
+	unsigned int		start_block:24;
+} __attribute__  ((packed)) squashfs_dir_inode_header_1;
+
+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
+	SQUASHFS_MEMSET(s, d, n);\
+	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
+	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
+	SQUASHFS_SWAP((s)->uid, d, 16, 4);\
+	SQUASHFS_SWAP((s)->guid, d, 20, 4);\
+}
+
+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, sizeof(squashfs_ipc_inode_header_1));\
+	SQUASHFS_SWAP((s)->type, d, 24, 4);\
+	SQUASHFS_SWAP((s)->offset, d, 28, 4);\
+}
+
+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, sizeof(squashfs_dev_inode_header_1));\
+	SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
+}
+
+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_symlink_inode_header_1));\
+	SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
+}
+
+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_reg_inode_header_1));\
+	SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
+	SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
+	SQUASHFS_SWAP((s)->file_size, d, 88, SQUASHFS_MAX_FILE_SIZE_LOG);\
+}
+
+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dir_inode_header_1));\
+	SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
+	SQUASHFS_SWAP((s)->offset, d, 43, 13);\
+	SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
+	SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
+}
+#endif
+
+#ifdef __KERNEL__
+/*
+ * macros used to swap each structure entry, taking into account
+ * bitfields and different bitfield placing conventions on differing architectures
+ */
+#include <asm/byteorder.h>
+#ifdef __BIG_ENDIAN
+	/* convert from little endian to big endian */
+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, b_pos)
+#else
+	/* convert from big endian to little endian */ 
+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, 64 - tbits - b_pos)
+#endif
+
+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
+	int bits;\
+	int b_pos = pos % 8;\
+	unsigned long long val = 0;\
+	unsigned char *s = (unsigned char *)p + (pos / 8);\
+	unsigned char *d = ((unsigned char *) &val) + 7;\
+	for(bits = 0; bits < (tbits + b_pos); bits += 8) \
+		*d-- = *s++;\
+	value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
+}
+#define SQUASHFS_MEMSET(s, d, n)	memset(s, 0, n);
+#endif
+#endif
diff --new-file -urp linux-2.6.13/include/linux/squashfs_fs_i.h linux-2.6.13-squashfs2.2-r2/include/linux/squashfs_fs_i.h
--- linux-2.6.13/include/linux/squashfs_fs_i.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.13-squashfs2.2-r2/include/linux/squashfs_fs_i.h	2005-09-09 00:39:17.000000000 +0100
@@ -0,0 +1,43 @@
+#ifndef SQUASHFS_FS_I
+#define SQUASHFS_FS_I
+/*
+ * Squashfs
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005 Phillip Lougher <phillip at lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs_fs_i.h
+ */
+
+typedef struct squashfs_inode_info {
+	unsigned int	start_block;
+	unsigned int	block_list_start;
+	unsigned int	offset;
+	union {
+		struct {
+			unsigned int	fragment_start_block;
+			unsigned int	fragment_size;
+			unsigned int	fragment_offset;
+		} s1;
+		struct {
+			unsigned int	directory_index_start;
+			unsigned int	directory_index_offset;
+			unsigned int	directory_index_count;
+		} s2;
+	} u;
+	struct inode	vfs_inode;
+	} squashfs_inode_info;
+#endif
diff --new-file -urp linux-2.6.13/include/linux/squashfs_fs_sb.h linux-2.6.13-squashfs2.2-r2/include/linux/squashfs_fs_sb.h
--- linux-2.6.13/include/linux/squashfs_fs_sb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.13-squashfs2.2-r2/include/linux/squashfs_fs_sb.h	2005-09-09 00:39:17.000000000 +0100
@@ -0,0 +1,65 @@
+#ifndef SQUASHFS_FS_SB
+#define SQUASHFS_FS_SB
+/*
+ * Squashfs
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005 Phillip Lougher <phillip at lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs_fs_sb.h
+ */
+
+#include <linux/squashfs_fs.h>
+
+typedef struct {
+	unsigned int	block;
+	int		length;
+	unsigned int	next_index;
+	char		*data;
+	} squashfs_cache;
+
+struct squashfs_fragment_cache {
+	unsigned int	block;
+	int		length;
+	unsigned int	locked;
+	char		*data;
+	};
+
+typedef struct squashfs_sb_info {
+	squashfs_super_block	sBlk;
+	int			devblksize;
+	int			devblksize_log2;
+	int			swap;
+	squashfs_cache		*block_cache;
+	struct squashfs_fragment_cache	*fragment;
+	int			next_cache;
+	int			next_fragment;
+	squashfs_uid		*uid;
+	squashfs_uid		*guid;
+	squashfs_fragment_index		*fragment_index;
+	unsigned int		read_size;
+	char			*read_data;
+	char			*read_page;
+	struct semaphore	read_page_mutex;
+	struct semaphore	block_cache_mutex;
+	struct semaphore	fragment_mutex;
+	wait_queue_head_t	waitq;
+	wait_queue_head_t	fragment_wait_queue;
+	struct inode		*(*iget)(struct super_block *s, squashfs_inode inode);
+	unsigned int		(*read_blocklist)(struct inode *inode, int index, int readahead_blks,
+					char *block_list, unsigned short **block_p, unsigned int *bsize);
+	} squashfs_sb_info;
+#endif

linux-2.6-swsusp-nofreeze.patch:
 ieee1394_core.c |    2 ++
 1 files changed, 2 insertions(+)

--- NEW FILE linux-2.6-swsusp-nofreeze.patch ---

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=166452

--- linux-2.6.13/drivers/ieee1394/ieee1394_core.c~	2005-10-06 00:18:56.000000000 -0400
+++ linux-2.6.13/drivers/ieee1394/ieee1394_core.c	2005-10-06 00:19:21.000000000 -0400
@@ -1030,6 +1030,8 @@ static int hpsbpkt_thread(void *__hi)
 
 	daemonize("khpsbpkt");
 
+	current->flags |= PF_NOFREEZE;
+
 	while (1) {
 		if (down_interruptible(&khpsbpkt_sig)) {
 			if (try_to_freeze())

linux-2.6-time-isr-ratelimit.patch:
 time.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-time-isr-ratelimit.patch ---
Ratelimit the "Timer ISR/0: Time went backwards: delta=..." timekeeping
messages.  Synchronous serial console results in floods of these messages.
---

 arch/i386/xen/kernel/time.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/i386/xen/kernel/time.c b/arch/i386/xen/kernel/time.c
index 4f896ca..0ab2cf5 100644
--- a/arch/i386/xen/kernel/time.c
+++ b/arch/i386/xen/kernel/time.c
@@ -567,7 +567,8 @@ irqreturn_t timer_interrupt(int irq, voi
 	}
 	while (!time_values_up_to_date(cpu));
 
-	if (unlikely(delta < -1000000LL) || unlikely(delta_cpu < 0)) {
+	if ((unlikely(delta < -1000000LL) || unlikely(delta_cpu < 0))
+	    && printk_ratelimit()) {
 		printk("Timer ISR/%d: Time went backwards: "
 		       "delta=%lld cpu_delta=%lld shadow=%lld "
 		       "off=%lld processed=%lld cpu_processed=%lld\n",

linux-2.6-tux.patch:
 arch/alpha/kernel/systbls.S      |    8 
 arch/i386/kernel/syscall_table.S |   10 
 arch/ia64/kernel/entry.S         |    8 
 arch/ia64/kernel/ia64_ksyms.c    |    5 
 arch/x86_64/ia32/ia32entry.S     |   10 
 fs/dcache.c                      |   36 
 fs/exec.c                        |    2 
 fs/fcntl.c                       |    4 
 fs/namei.c                       |   18 
 fs/namespace.c                   |    2 
 fs/open.c                        |    4 
 fs/pipe.c                        |    2 
 fs/read_write.c                  |    2 
 include/asm-alpha/fcntl.h        |    1 
 include/asm-generic/fcntl.h      |    4 
 include/asm-i386/unistd.h        |    5 
 include/asm-ia64/unistd.h        |    2 
 include/asm-sparc/fcntl.h        |    1 
 include/asm-sparc64/fcntl.h      |    1 
 include/asm-x86_64/unistd.h      |   10 
 include/linux/buffer_head.h      |    1 
 include/linux/dcache.h           |    8 
 include/linux/errno.h            |    3 
 include/linux/file.h             |    2 
 include/linux/fs.h               |    7 
 include/linux/kmod.h             |    2 
 include/linux/namei.h            |    2 
 include/linux/net.h              |    1 
 include/linux/sched.h            |    5 
 include/linux/skbuff.h           |    2 
 include/linux/socket.h           |    5 
 include/linux/sysctl.h           |   50 
 include/net/sock.h               |    8 
 include/net/tcp.h                |    3 
 include/net/tux.h                |  804 ++++++++++++++
 include/net/tux_u.h              |  163 ++
 kernel/exit.c                    |    7 
 kernel/fork.c                    |    1 
 kernel/kmod.c                    |   28 
 kernel/signal.c                  |    1 
 mm/filemap.c                     |   19 
 mm/truncate.c                    |    2 
 net/Kconfig                      |    1 
 net/Makefile                     |    1 
 net/core/sock.c                  |    5 
 net/ipv4/tcp.c                   |    3 
 net/ipv4/tcp_input.c             |    1 
 net/ipv4/tcp_output.c            |    1 
 net/socket.c                     |  197 ++-
 net/tux/Kconfig                  |   25 
 net/tux/Makefile                 |   12 
 net/tux/abuf.c                   |  190 +++
 net/tux/accept.c                 |  863 +++++++++++++++
 net/tux/cachemiss.c              |  265 ++++
 net/tux/cgi.c                    |  171 +++
 net/tux/directory.c              |  302 +++++
 net/tux/extcgi.c                 |  329 +++++
 net/tux/gzip.c                   |   40 
 net/tux/input.c                  |  641 +++++++++++
 net/tux/logger.c                 |  837 ++++++++++++++
 net/tux/main.c                   | 1417 +++++++++++++++++++++++++
 net/tux/mod.c                    |  262 ++++
 net/tux/output.c                 |  352 ++++++
 net/tux/parser.h                 |  102 +
 net/tux/postpone.c               |   77 +
 net/tux/proc.c                   | 1149 ++++++++++++++++++++
 net/tux/proto_ftp.c              | 1555 +++++++++++++++++++++++++++
 net/tux/proto_http.c             | 2197 +++++++++++++++++++++++++++++++++++++++
 net/tux/redirect.c               |  172 +++
 net/tux/times.c                  |  392 ++++++
 net/tux/times.h                  |   26 
 net/tux/userspace.c              |   27 
 72 files changed, 12773 insertions(+), 98 deletions(-)

--- NEW FILE linux-2.6-tux.patch ---
 arch/alpha/kernel/systbls.S      |    8 
 arch/i386/kernel/syscall_table.S |   10 
 arch/ia64/kernel/entry.S         |    8 
 arch/ia64/kernel/ia64_ksyms.c    |    5 
 arch/x86_64/ia32/ia32entry.S     |   10 
 fs/dcache.c                      |   36 
 fs/exec.c                        |    2 
 fs/fcntl.c                       |    4 
 fs/namei.c                       |   18 
 fs/namespace.c                   |    2 
 fs/open.c                        |    4 
 fs/pipe.c                        |    2 
 fs/read_write.c                  |    2 
 include/asm-alpha/fcntl.h        |    1 
 include/asm-generic/fcntl.h      |    4 
 include/asm-i386/unistd.h        |    5 
 include/asm-ia64/unistd.h        |    2 
 include/asm-sparc/fcntl.h        |    1 
 include/asm-sparc64/fcntl.h      |    1 
 include/asm-x86_64/unistd.h      |   10 
 include/linux/buffer_head.h      |    1 
 include/linux/dcache.h           |    8 
 include/linux/errno.h            |    3 
 include/linux/file.h             |    2 
 include/linux/fs.h               |    7 
 include/linux/kmod.h             |    2 
 include/linux/namei.h            |    2 
 include/linux/net.h              |    1 
 include/linux/sched.h            |    5 
 include/linux/skbuff.h           |    2 
 include/linux/socket.h           |    5 
 include/linux/sysctl.h           |   50 
 include/net/sock.h               |    8 
 include/net/tcp.h                |    3 
 include/net/tux.h                |  804 ++++++++++++++
 include/net/tux_u.h              |  163 ++
 kernel/exit.c                    |    7 
 kernel/fork.c                    |    1 
 kernel/kmod.c                    |   28 
 kernel/signal.c                  |    1 
 mm/filemap.c                     |   19 
 mm/truncate.c                    |    2 
 net/Kconfig                      |    1 
 net/Makefile                     |    1 
 net/core/sock.c                  |    5 
 net/ipv4/tcp.c                   |    3 
 net/ipv4/tcp_input.c             |    1 
 net/ipv4/tcp_output.c            |    1 
 net/socket.c                     |  197 ++-
 net/tux/Kconfig                  |   25 
 net/tux/Makefile                 |   12 
 net/tux/abuf.c                   |  190 +++
 net/tux/accept.c                 |  863 +++++++++++++++
 net/tux/cachemiss.c              |  265 ++++
 net/tux/cgi.c                    |  171 +++
 net/tux/directory.c              |  302 +++++
 net/tux/extcgi.c                 |  329 +++++
 net/tux/gzip.c                   |   40 
 net/tux/input.c                  |  641 +++++++++++
 net/tux/logger.c                 |  837 ++++++++++++++
 net/tux/main.c                   | 1417 +++++++++++++++++++++++++
 net/tux/mod.c                    |  262 ++++
 net/tux/output.c                 |  352 ++++++
 net/tux/parser.h                 |  102 +
 net/tux/postpone.c               |   77 +
 net/tux/proc.c                   | 1149 ++++++++++++++++++++
 net/tux/proto_ftp.c              | 1555 +++++++++++++++++++++++++++
 net/tux/proto_http.c             | 2197 +++++++++++++++++++++++++++++++++++++++
 net/tux/redirect.c               |  172 +++
 net/tux/times.c                  |  392 ++++++
 net/tux/times.h                  |   26 
 net/tux/userspace.c              |   27 
 72 files changed, 12773 insertions(+), 98 deletions(-)

Index: linux/arch/alpha/kernel/systbls.S
===================================================================
--- linux.orig/arch/alpha/kernel/systbls.S
+++ linux/arch/alpha/kernel/systbls.S
@@ -240,7 +240,15 @@ sys_call_table:
 	.quad alpha_ni_syscall
 	.quad alpha_ni_syscall			/* 220 */
 	.quad alpha_ni_syscall
+#ifdef CONFIG_TUX
+	.quad __sys_tux
+#else
+# ifdef CONFIG_TUX_MODULE
+	.quad sys_tux
+# else
 	.quad alpha_ni_syscall
+# endif
+#endif
 	.quad alpha_ni_syscall
 	.quad alpha_ni_syscall
 	.quad alpha_ni_syscall			/* 225 */
Index: linux/arch/i386/kernel/syscall_table.S
===================================================================
--- linux.orig/arch/i386/kernel/syscall_table.S
+++ linux/arch/i386/kernel/syscall_table.S
@@ -222,7 +222,15 @@ ENTRY(sys_call_table)
 	.long sys_madvise
 	.long sys_getdents64	/* 220 */
 	.long sys_fcntl64
-	.long sys_ni_syscall	/* reserved for TUX */
+#ifdef CONFIG_TUX
+	.long __sys_tux
+#else
+# ifdef CONFIG_TUX_MODULE
+	.long sys_tux
+# else
+	.long sys_ni_syscall
+# endif
+#endif
 	.long sys_ni_syscall
 	.long sys_gettid
 	.long sys_readahead	/* 225 */
Index: linux/arch/ia64/kernel/entry.S
===================================================================
--- linux.orig/arch/ia64/kernel/entry.S
+++ linux/arch/ia64/kernel/entry.S
@@ -1440,7 +1440,15 @@ sys_call_table:
 	data8 sys_syslog
 	data8 sys_setitimer
 	data8 sys_getitimer
+#ifdef CONFIG_TUX
+	data8 __sys_tux				// 1120		/* was: ia64_oldstat */
+#else
+# ifdef CONFIG_TUX_MODULE
+	data8 sys_tux				// 1120		/* was: ia64_oldstat */
+# else
 	data8 sys_ni_syscall			// 1120		/* was: ia64_oldstat */
+# endif
+#endif
 	data8 sys_ni_syscall					/* was: ia64_oldlstat */
 	data8 sys_ni_syscall					/* was: ia64_oldfstat */
 	data8 sys_vhangup
Index: linux/arch/ia64/kernel/ia64_ksyms.c
===================================================================
--- linux.orig/arch/ia64/kernel/ia64_ksyms.c
+++ linux/arch/ia64/kernel/ia64_ksyms.c
@@ -58,6 +58,11 @@ EXPORT_SYMBOL(__strlen_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(__strnlen_user);
 
+#define __KERNEL_SYSCALLS__
+#include <asm/unistd.h>
+EXPORT_SYMBOL(sys_execve);
+EXPORT_SYMBOL(clone);
+
 /* from arch/ia64/lib */
 extern void __divsi3(void);
 extern void __udivsi3(void);
Index: linux/arch/x86_64/ia32/ia32entry.S
===================================================================
--- linux.orig/arch/x86_64/ia32/ia32entry.S
+++ linux/arch/x86_64/ia32/ia32entry.S
@@ -571,7 +571,15 @@ ia32_sys_call_table:
 	.quad sys_madvise
 	.quad compat_sys_getdents64	/* 220 getdents64 */
 	.quad compat_sys_fcntl64	
-	.quad quiet_ni_syscall		/* tux */
+#ifdef CONFIG_TUX
+	.quad __sys_tux
+#else
+# ifdef CONFIG_TUX_MODULE
+	.quad sys_tux
+# else
+	.quad quiet_ni_syscall
+# endif
+#endif
 	.quad quiet_ni_syscall    	/* security */
 	.quad sys_gettid	
 	.quad sys_readahead	/* 225 */
Index: linux/fs/dcache.c
===================================================================
--- linux.orig/fs/dcache.c
+++ linux/fs/dcache.c
@@ -86,6 +86,10 @@ static void d_free(struct dentry *dentry
 {
 	if (dentry->d_op && dentry->d_op->d_release)
 		dentry->d_op->d_release(dentry);
+	if (dentry->d_extra_attributes) {
+		kfree(dentry->d_extra_attributes);
+		dentry->d_extra_attributes = NULL;
+	}
  	call_rcu(&dentry->d_rcu, d_callback);
 }
 
@@ -742,6 +746,7 @@ struct dentry *d_alloc(struct dentry * p
 	dentry->d_sb = NULL;
 	dentry->d_op = NULL;
 	dentry->d_fsdata = NULL;
+	dentry->d_extra_attributes = NULL;
 	dentry->d_mounted = 0;
 	dentry->d_cookie = NULL;
 	INIT_HLIST_NODE(&dentry->d_hash);
@@ -1310,6 +1315,16 @@ already_unhashed:
 	/* Unhash the target: dput() will then get rid of it */
 	__d_drop(target);
 
[...13455 lines suppressed...]
+	hour = tod / 3600;
+	tod %= 3600;
+	min = tod / 60;
+	sec = tod % 60;
+
+	wday = (day + 4) % 7;
+	if (wday < 0)
+		wday += 7;
+
+	day -= 11017;
+	/* day 0 is march 1, 2000 */
+	year = 5 + day / 146097;
+	day = day % 146097;
+	if (day < 0) {
+		day += 146097;
+		--year;
+	}
+	/* from now on, day is nonnegative */
+	year *= 4;
+	if (day == 146096) {
+		year += 3;
+		day = 36524;
+	} else {
+		year += day / 36524;
+		day %= 36524;
+	}
+	year *= 25;
+	year += day / 1461;
+	day %= 1461;
+	year *= 4;
+	if (day == 1460) {
+		year += 3;
+		day = 365;
+	} else {
+		year += day / 365;
+		day %= 365;
+	}
+
+	day *= 10;
+	mon = (day + 5) / 306;
+	day = day + 5 - 306 * mon;
+	day /= 10;
+	if (mon >= 10) {
+		++year;
+		mon -= 10;
+	} else
+		mon += 2;
+
+	return sprintf(curr, "213 %.4d%.2d%.2d%.2d%.2d%.2d\r\n",
+		year, mon+1, day+1, hour, min, sec);
+}
+
+static inline int make_num(const char *s)
+{
+	if (*s >= '0' && *s <= '9')
+		return 10 * (*s - '0') + *(s + 1) - '0';
+	else
+		return *(s + 1) - '0';
+}
+
+static inline int make_month(const char *s)
+{
+	int i;
+
+	for (i = 0; i < 12; i++)
+		if (!strncmp(monthName[i], s, 3))
+			return i+1;
+	return 0;
+}
+
+time_t parse_time(const char *str, const int str_len)
+{
+	int hour;
+	int min;
+	int sec;
+	int mday;
+	int mon;
+	int year;
+
+	if (str[3] == ',') {
+		/* Thu, 09 Jan 1993 01:29:59 GMT */
+
+		if (str_len < 29)
+			return -1;
+
+		mday = make_num(str+5);
+		mon = make_month(str + 8);
+		year = 100 * make_num(str + 12) + make_num(str + 14);
+		hour = make_num(str + 17);
+		min = make_num(str + 20);
+		sec = make_num(str + 23);
+	}
+	else {
+		const char *s;
+		s = strchr(str, ',');
+		if (!s || (str_len - (s - str) < 24)) {
+			/* Wed Jun  9 01:29:59 1993 */
+
+			if (str_len < 24)
+                        	return -1;
+
+			mon = make_month(str+4);
+			mday = make_num(str+8);
+			hour = make_num(str+11);
+			min = make_num(str+14);
+			sec = make_num(str+17);
+			year = make_num(str+20)*100 + make_num(str+22);
+		}
+		else {
+			/* Thursday, 10-Jun-93 01:29:59 GMT */
+
+			mday = make_num(s + 2);
+			mon = make_month(s + 5);
+			year = make_num(s + 9) + 1900;
+			if (year < 1970)
+				year += 100;
+			hour = make_num(s + 12);
+			min = make_num(s + 15);
+			sec = make_num(s + 18);
+		}
+	}
+
+	if (sec < 0 || sec > 59)
+		return -1;
+	if (min < 0 || min > 59)
+		return -1;
+	if (hour < 0 || hour > 23)
+		return -1;
+	if (mday < 1 || mday > 31)
+		return -1;
+	if (mon < 1 || mon > 12)
+		return -1;
+	if (year < 1970 || year > 2020)
+		return -1;
+
+	return mktime(year, mon, mday, hour, min, sec);
+}
Index: linux/net/tux/times.h
===================================================================
--- /dev/null
+++ linux/net/tux/times.h
@@ -0,0 +1,26 @@
+static time_t TimeDays[10][13] = {
+ { 852073200,	854751600,	857170800,	859849200,	862441200,	865119600,	867711600,	870390000,	873068400,	875660400,	878338800,	880930800,	883609200 } ,
+ { 883609200,	886287600,	888706800,	891385200,	893977200,	896655600,	899247600,	901926000,	904604400,	907196400,	909874800,	912466800,	915145200 } ,
+ { 915145200,	917823600,	920242800,	922921200,	925513200,	928191600,	930783600,	933462000,	936140400,	938732400,	941410800,	944002800,	946681200 } ,
+ { 946681200,	949359600,	951865200,	954543600,	957135600,	959814000,	962406000,	965084400,	967762800,	970354800,	973033200,	975625200,	978303600 } ,
+ { 978303600,	980982000,	983401200,	986079600,	988671600,	991350000,	993942000,	996620400,	999298800,	1001890800,	1004569200,	1007161200,	1009839600 } ,
+ { 1009839600,	1012518000,	1014937200,	1017615600,	1020207600,	1022886000,	1025478000,	1028156400,	1030834800,	1033426800,	1036105200,	1038697200,	1041375600 } ,
+ { 1041375600,	1044054000,	1046473200,	1049151600,	1051743600,	1054422000,	1057014000,	1059692400,	1062370800,	1064962800,	1067641200,	1070233200,	1072911600 } ,
+ { 1072911600,	1075590000,	1078095600,	1080774000,	1083366000,	1086044400,	1088636400,	1091314800,	1093993200,	1096585200,	1099263600,	1101855600,	1104534000 } ,
+ { 1104534000,	1107212400,	1109631600,	1112310000,	1114902000,	1117580400,	1120172400,	1122850800,	1125529200,	1128121200,	1130799600,	1133391600,	1136070000 } ,
+ { 1136070000,	1138748400,	1141167600,	1143846000,	1146438000,	1149116400,	1151708400,	1154386800,	1157065200,	1159657200,	1162335600,	1164927600,	1167606000 }
+};
+static int WeekDays[10][13] = {
+ { 3,	6,	6,	2,	4,	0,	2,	5,	1,	3,	6,	1,	4 } ,
+ { 4,	0,	0,	3,	5,	1,	3,	6,	2,	4,	0,	2,	5 } ,
+ { 5,	1,	1,	4,	6,	2,	4,	0,	3,	5,	1,	3,	6 } ,
+ { 6,	2,	3,	6,	1,	4,	6,	2,	5,	0,	3,	5,	1 } ,
+ { 1,	4,	4,	0,	2,	5,	0,	3,	6,	1,	4,	6,	2 } ,
+ { 2,	5,	5,	1,	3,	6,	1,	4,	0,	2,	5,	0,	3 } ,
+ { 3,	6,	6,	2,	4,	0,	2,	5,	1,	3,	6,	1,	4 } ,
+ { 4,	0,	1,	4,	6,	2,	4,	0,	3,	5,	1,	3,	6 } ,
+ { 6,	2,	2,	5,	0,	3,	5,	1,	4,	6,	2,	4,	0 } ,
+ { 0,	3,	3,	6,	1,	4,	6,	2,	5,	0,	3,	5,	1 }
+};
+#define TUX_YEAROFFSET   1997
+#define TUX_NUMYEARS     10
Index: linux/net/tux/userspace.c
===================================================================
--- /dev/null
+++ linux/net/tux/userspace.c
@@ -0,0 +1,27 @@
+/*
+ * TUX - Integrated Application Protocols Layer and Object Cache
+ *
+ * Copyright (C) 2000, 2001, Ingo Molnar <mingo at redhat.com>
+ *
+ * userspace.c: handle userspace-module requests
+ */
+
+#include <net/tux.h>
+
+/****************************************************************
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2, or (at your option)
+ *      any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ****************************************************************/
+

linux-2.6-ub.patch:
 linux-2.6.14-1.1674_FC5-ub/drivers/block/Kconfig              |    3 
 linux-2.6.14-1.1674_FC5-ub/drivers/block/ub.c                 |   23 
 linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/Kconfig        |   14 
 linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/Makefile       |    4 
 linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/libusual.c     |  266 ++++++++++
 linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/protocol.h     |   14 
 linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/transport.h    |   31 -
 linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/unusual_devs.h |   24 
 linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/usb.c          |  123 +---
 linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/usb.h          |   31 -
 linux-2.6.14-1.1674_FC5-ub/include/linux/usb_usual.h          |  123 ++++
 linux-2.6.14/drivers/usb/Makefile                             |    1 
 12 files changed, 486 insertions(+), 171 deletions(-)

--- NEW FILE linux-2.6-ub.patch ---
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/block/Kconfig linux-2.6.14-1.1674_FC5-ub/drivers/block/Kconfig
--- linux-2.6.14-1.1674_FC5/drivers/block/Kconfig	2005-11-15 12:20:27.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/drivers/block/Kconfig	2005-11-15 13:30:19.000000000 -0800
@@ -358,7 +358,8 @@ config BLK_DEV_UB
 	  This driver supports certain USB attached storage devices
 	  such as flash keys.
 
-	  Warning: Enabling this cripples the usb-storage driver.
+	  If you enable this driver, it is recommended to avoid conflicts
+	  with usb-storage by enabling USB_LIBUSUAL.
 
 	  If unsure, say N.
 
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/block/ub.c linux-2.6.14-1.1674_FC5-ub/drivers/block/ub.c
--- linux-2.6.14-1.1674_FC5/drivers/block/ub.c	2005-11-15 12:19:32.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/drivers/block/ub.c	2005-11-15 13:30:19.000000000 -0800
@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/timer.h>
@@ -107,16 +108,6 @@
  */
 
 /*
- * Definitions which have to be scattered once we understand the layout better.
- */
-
-/* Transport (despite PR in the name) */
-#define US_PR_BULK	0x50		/* bulk only */
-
-/* Protocol */
-#define US_SC_SCSI	0x06		/* Transparent */
-
-/*
  * This many LUNs per USB device.
  * Every one of them takes a host, see UB_MAX_HOSTS.
  */
@@ -422,13 +413,18 @@ static int ub_probe_lun(struct ub_dev *s
 
 /*
  */
+#ifdef CONFIG_USB_LIBUSUAL
+
+#define ub_usb_ids  storage_usb_ids
+#else
+
 static struct usb_device_id ub_usb_ids[] = {
-	// { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) },	/* SDDR-31 */
 	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
 	{ }
 };
 
 MODULE_DEVICE_TABLE(usb, ub_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
 
 /*
  * Find me a way to identify "next free minor" for add_disk(),
@@ -2172,6 +2168,9 @@ static int ub_probe(struct usb_interface
 	int rc;
 	int i;
 
+	if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))
+		return -ENXIO;
+
 	rc = -ENOMEM;
 	if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
 		goto err_core;
@@ -2479,6 +2478,7 @@ static int __init ub_init(void)
 	if ((rc = usb_register(&ub_driver)) != 0)
 		goto err_register;
 
+	usb_usual_set_present(USB_US_TYPE_UB);
 	return 0;
 
 err_register:
@@ -2494,6 +2494,7 @@ static void __exit ub_exit(void)
 
 	devfs_remove(DEVFS_NAME);
 	unregister_blkdev(UB_MAJOR, DRV_NAME);
+	usb_usual_clear_present(USB_US_TYPE_UB);
 }
 
 module_init(ub_init);
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/usb/storage/Kconfig linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/Kconfig
--- linux-2.6.14-1.1674_FC5/drivers/usb/storage/Kconfig	2005-11-15 12:19:56.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/Kconfig	2005-11-15 13:30:19.000000000 -0800
@@ -124,3 +124,17 @@ config USB_STORAGE_ONETOUCH
 	  hard drive's as an input device. An action can be associated with
 	  this input in any keybinding software. (e.g. gnome's keyboard short-
 	  cuts)
+
+config USB_LIBUSUAL
+	bool "The shared table of common (or usual) storage devices"
+	depends on USB
+	help
+	  This module contains a table of common (or usual) devices
+	  for usb-storage and ub drivers, and allows to switch binding
+	  of these devices without rebuilding modules.
+
+	  Typical syntax of /etc/modprobe.conf is:
+
+		options libusual bias="ub"
+
+	  If unsure, say N.
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/usb/storage/libusual.c linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/libusual.c
--- linux-2.6.14-1.1674_FC5/drivers/usb/storage/libusual.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/libusual.c	2005-11-15 13:30:19.000000000 -0800
@@ -0,0 +1,266 @@
+/*
+ * libusual
+ *
+ * The libusual contains the table of devices common for ub and usb-storage.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+#include <linux/vmalloc.h>
+
+/*
+ */
+#define USU_MOD_FL_THREAD   1	/* Thread is running */
+#define USU_MOD_FL_PRESENT  2	/* The module is loaded */
+
+struct mod_status {
+	unsigned long fls;
+};
+
+static struct mod_status stat[3];
+static DEFINE_SPINLOCK(usu_lock);
+
+/*
+ */
+#define USB_US_DEFAULT_BIAS	USB_US_TYPE_STOR
+
+#define BIAS_NAME_SIZE  (sizeof("usb-storage"))
+static char bias[BIAS_NAME_SIZE];
+static int usb_usual_bias;
+static const char *bias_names[3] = { "none", "usb-storage", "ub" };
+
+static DECLARE_MUTEX_LOCKED(usu_init_notify);
+static DECLARE_COMPLETION(usu_end_notify);
+static atomic_t total_threads = ATOMIC_INIT(0);
+
+static int usu_probe_thread(void *arg);
+static int parse_bias(const char *bias_s);
+
+/*
+ * The table.
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+		    vendorName, productName,useProtocol, useTransport, \
+		    initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = ((useType)<<24) }
+
+struct usb_device_id storage_usb_ids [] = {
+#	include "unusual_devs.h"
+	{ } /* Terminating entry */
+};
+
+#undef USUAL_DEV
+#undef UNUSUAL_DEV
+
+MODULE_DEVICE_TABLE(usb, storage_usb_ids);
+EXPORT_SYMBOL(storage_usb_ids);
+
+/*
+ * @type: the module type as an integer
+ */
+void usb_usual_set_present(int type)
+{
+	struct mod_status *st;
+	unsigned long flags;
+
+	if (type <= 0 || type >= 3)
+		return;
+	st = &stat[type];
+	spin_lock_irqsave(&usu_lock, flags);
+	st->fls |= USU_MOD_FL_PRESENT;
+	spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL(usb_usual_set_present);
+
+void usb_usual_clear_present(int type)
+{
+	struct mod_status *st;
+	unsigned long flags;
+
+	if (type <= 0 || type >= 3)
+		return;
+	st = &stat[type];
+	spin_lock_irqsave(&usu_lock, flags);
+	st->fls &= ~USU_MOD_FL_PRESENT;
+	spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL(usb_usual_clear_present);
+
+/*
+ * Match the calling driver type against the table.
+ * Returns: 0 if the device matches.
+ */
+int usb_usual_check_type(const struct usb_device_id *id, int caller_type)
+{
+	int id_type = USB_US_TYPE(id->driver_info);
+
+	if (caller_type <= 0 || caller_type >= 3)
+		return -EINVAL;
+
+	/* Drivers grab fixed assignment devices */
+	if (id_type == caller_type)
+		return 0;
+	/* Drivers grab devices biased to them */
+	if (id_type == USB_US_TYPE_NONE && caller_type == usb_usual_bias)
+		return 0;
+	return -ENODEV;
+}
+EXPORT_SYMBOL(usb_usual_check_type);
+
+/*
+ */
+static int usu_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
+{
+	int type;
+	int rc;
+	unsigned long flags;
+
+	type = USB_US_TYPE(id->driver_info);
+	if (type == 0)
+		type = usb_usual_bias;
+
+	spin_lock_irqsave(&usu_lock, flags);
+	if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) {
+		spin_unlock_irqrestore(&usu_lock, flags);
+		return -ENXIO;
+	}
+	stat[type].fls |= USU_MOD_FL_THREAD;
+	spin_unlock_irqrestore(&usu_lock, flags);
+
+	rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM);
+	if (rc < 0) {
+		printk(KERN_WARNING "libusual: "
+		    "Unable to start the thread for %s: %d\n",
+		    bias_names[type], rc);
+		spin_lock_irqsave(&usu_lock, flags);
+		stat[type].fls &= ~USU_MOD_FL_THREAD;
+		spin_unlock_irqrestore(&usu_lock, flags);
+		return rc;	/* Not being -ENXIO causes a message printed */
+	}
+	atomic_inc(&total_threads);
+
+	return -ENXIO;
+}
+
+static void usu_disconnect(struct usb_interface *intf)
+{
+	;	/* We should not be here. */
+}
+
+static struct usb_driver usu_driver = {
+	.owner =	THIS_MODULE,
+	.name =		"libusual",
+	.probe =	usu_probe,
+	.disconnect =	usu_disconnect,
+	.id_table =	storage_usb_ids,
+};
+
+/*
+ * A whole new thread for a purpose of request_module seems quite stupid.
+ * The request_module forks once inside again. However, if we attempt
+ * to load a storage module from our own modprobe thread, that module
+ * references our symbols, which cannot be resolved until our module is
+ * initialized. I wish there was a way to wait for the end of initialization.
+ * The module notifier reports MODULE_STATE_COMING only.
+ * So, we wait until module->init ends as the next best thing.
+ */
+static int usu_probe_thread(void *arg)
+{
+	int type = (unsigned long) arg;
+	struct mod_status *st = &stat[type];
+	int rc;
+	unsigned long flags;
+
+	daemonize("libusual_%d", type);	/* "usb-storage" is kinda too long */
+
+	/* A completion does not work here because it's counted. */
+	down(&usu_init_notify);
+	up(&usu_init_notify);
+
+	rc = request_module(bias_names[type]);
+	spin_lock_irqsave(&usu_lock, flags);
+	if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) {
+		/*
+		 * This should not happen, but let us keep tabs on it.
+		 */
+		printk(KERN_NOTICE "libusual: "
+		    "modprobe for %s succeeded, but module is not present\n",
+		    bias_names[type]);
+	}
+	st->fls &= ~USU_MOD_FL_THREAD;
+	spin_unlock_irqrestore(&usu_lock, flags);
+
+	complete_and_exit(&usu_end_notify, 0);
+}
+
+/*
+ */
+static int __init usb_usual_init(void)
+{
+	int rc;
+
+	bias[BIAS_NAME_SIZE-1] = 0;
+	usb_usual_bias = parse_bias(bias);
+
+	rc = usb_register(&usu_driver);
+	up(&usu_init_notify);
+	return rc;
+}
+
+static void __exit usb_usual_exit(void)
+{
+	/*
+	 * We do not check for any drivers present, because
+	 * they keep us pinned with symbol references.
+	 */
+
+	usb_deregister(&usu_driver);
+
+	while (atomic_read(&total_threads) > 0) {
+		wait_for_completion(&usu_end_notify);
+		atomic_dec(&total_threads);
+	}
+}
+
+/*
+ * Validate and accept the bias parameter.
+ * Maybe make an sysfs method later. XXX
+ */
+static int parse_bias(const char *bias_s)
+{
+	int i;
+	int bias_n = 0;
+
+	if (bias_s[0] == 0 || bias_s[0] == ' ') {
+		bias_n = USB_US_DEFAULT_BIAS;
+	} else {
+		for (i = 1; i < 3; i++) {
+			if (strcmp(bias_s, bias_names[i]) == 0) {
+				bias_n = i;
+				break;
+			}
+		}
+		if (bias_n == 0) {
+			bias_n = USB_US_DEFAULT_BIAS;
+			printk(KERN_INFO
+			    "libusual: unknown bias \"%s\", using \"%s\"\n",
+			    bias_s, bias_names[bias_n]);
+		}
+	}
+	return bias_n;
+}
+
+module_init(usb_usual_init);
+module_exit(usb_usual_exit);
+
+module_param_string(bias, bias, BIAS_NAME_SIZE,  S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(bias, "Bias to usb-storage or ub");
+
+MODULE_LICENSE("GPL");
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/usb/storage/Makefile linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/Makefile
--- linux-2.6.14-1.1674_FC5/drivers/usb/storage/Makefile	2005-10-27 17:02:08.000000000 -0700
+++ linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/Makefile	2005-11-15 13:30:19.000000000 -0800
@@ -22,3 +22,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_ONE
 
 usb-storage-objs :=	scsiglue.o protocol.o transport.o usb.o \
 			initializers.o $(usb-storage-obj-y)
+
+ifneq ($(CONFIG_USB_LIBUSUAL),)
+	obj-$(CONFIG_USB)	+= libusual.o
+endif
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/usb/storage/protocol.h linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/protocol.h
--- linux-2.6.14-1.1674_FC5/drivers/usb/storage/protocol.h	2005-10-27 17:02:08.000000000 -0700
+++ linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/protocol.h	2005-11-15 13:30:19.000000000 -0800
@@ -41,20 +41,6 @@
 #ifndef _PROTOCOL_H_
 #define _PROTOCOL_H_
 
-/* Sub Classes */
-
-#define US_SC_RBC	0x01		/* Typically, flash devices */
-#define US_SC_8020	0x02		/* CD-ROM */
-#define US_SC_QIC	0x03		/* QIC-157 Tapes */
-#define US_SC_UFI	0x04		/* Floppy */
-#define US_SC_8070	0x05		/* Removable media */
-#define US_SC_SCSI	0x06		/* Transparent */
-#define US_SC_ISD200    0x07		/* ISD200 ATA */
-#define US_SC_MIN	US_SC_RBC
-#define US_SC_MAX	US_SC_ISD200
-
-#define US_SC_DEVICE	0xff		/* Use device's value */
-
 /* Protocol handling routines */
 extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*);
 extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*);
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/usb/storage/transport.h linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/transport.h
--- linux-2.6.14-1.1674_FC5/drivers/usb/storage/transport.h	2005-11-15 12:19:56.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/transport.h	2005-11-15 13:36:41.000000000 -0800
@@ -41,39 +41,8 @@
 #ifndef _TRANSPORT_H_
 #define _TRANSPORT_H_
 
-#include <linux/config.h>
 #include <linux/blkdev.h>
 
-/* Protocols */
-
-#define US_PR_CBI	0x00		/* Control/Bulk/Interrupt */
-#define US_PR_CB	0x01		/* Control/Bulk w/o interrupt */
-#define US_PR_BULK	0x50		/* bulk only */
-#ifdef CONFIG_USB_STORAGE_USBAT
-#define US_PR_USBAT	0x80		/* SCM-ATAPI bridge */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
-#define US_PR_EUSB_SDDR09	0x81	/* SCM-SCSI bridge for SDDR-09 */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-#define US_PR_SDDR55	0x82		/* SDDR-55 (made up) */
-#endif
-#define US_PR_DPCM_USB  0xf0		/* Combination CB/SDDR09 */
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-#define US_PR_FREECOM   0xf1		/* Freecom */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-#define US_PR_DATAFAB   0xf2		/* Datafab chipsets */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#define US_PR_JUMPSHOT  0xf3		/* Lexar Jumpshot */
-#endif
-
-#define US_PR_DEVICE	0xff		/* Use device's value */
-
 /*
  * Bulk only data structures
  */
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/usb/storage/unusual_devs.h linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/unusual_devs.h
--- linux-2.6.14-1.1674_FC5/drivers/usb/storage/unusual_devs.h	2005-11-15 12:19:56.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/unusual_devs.h	2005-11-15 13:30:20.000000000 -0800
@@ -1125,3 +1125,27 @@ UNUSUAL_DEV(  0x55aa, 0xa103, 0x0000, 0x
 		US_SC_SCSI, US_PR_SDDR55, NULL,
 		US_FL_SINGLE_LUN),
 #endif
+
+/* Control/Bulk transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR),
+
+/* Control/Bulk/Interrupt transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR),
+
+/* Bulk-only transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0),
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/usb/storage/usb.c linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/usb.c
--- linux-2.6.14-1.1674_FC5/drivers/usb/storage/usb.c	2005-11-15 12:19:56.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/usb.c	2005-11-15 13:38:47.000000000 -0800
@@ -112,49 +112,33 @@ static atomic_t total_threads = ATOMIC_I
 static DECLARE_COMPLETION(threads_gone);
 
 
-/* The entries in this table, except for final ones here
- * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
- * line for line with the entries of us_unsuaul_dev_list[].
+/*
+ * The entries in this table correspond, line for line,
+ * with the entries of us_unusual_dev_list[].
  */
+#ifndef CONFIG_USB_LIBUSUAL
 
 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
 		    vendorName, productName,useProtocol, useTransport, \
 		    initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) }
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = (USB_US_TYPE_STOR<<24) }
 
 static struct usb_device_id storage_usb_ids [] = {
 
 #	include "unusual_devs.h"
 #undef UNUSUAL_DEV
-	/* Control/Bulk transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) },
-
-	/* Control/Bulk/Interrupt transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) },
-
-	/* Bulk-only transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
-
+#undef USUAL_DEV
 	/* Terminating entry */
 	{ }
 };
 
 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
 
 /* This is the list of devices we recognize, along with their flag data */
 
@@ -167,7 +151,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_id
  * are free to use as many characters as you like.
  */
 
-#undef UNUSUAL_DEV
 #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
 		    vendor_name, product_name, use_protocol, use_transport, \
 		    init_function, Flags) \
@@ -177,53 +160,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_id
 	.useProtocol = use_protocol,	\
 	.useTransport = use_transport,	\
 	.initFunction = init_function,	\
-	.flags = Flags, \
+}
+
+#define USUAL_DEV(use_protocol, use_transport, use_type) \
+{ \
+	.useProtocol = use_protocol,	\
+	.useTransport = use_transport,	\
 }
 
 static struct us_unusual_dev us_unusual_dev_list[] = {
 #	include "unusual_devs.h" 
 #	undef UNUSUAL_DEV
-	/* Control/Bulk transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_CB},
-
-	/* Control/Bulk/Interrupt transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_CBI},
-
-	/* Bulk-only transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_BULK},
+#	undef USUAL_DEV
 
 	/* Terminating entry */
 	{ NULL }
@@ -483,15 +431,21 @@ static int associate_dev(struct us_data 
 	}
 	return 0;
 }
+ 
+/* Find an unusual_dev descriptor (always succeeds in the current code) */
+static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
+{
+	const int id_index = id - storage_usb_ids;
+	return &us_unusual_dev_list[id_index];
+}
 
 /* Get the unusual_devs entries and the string descriptors */
-static void get_device_info(struct us_data *us, int id_index)
+static void get_device_info(struct us_data *us, const struct usb_device_id *id)
 {
 	struct usb_device *dev = us->pusb_dev;
 	struct usb_interface_descriptor *idesc =
 		&us->pusb_intf->cur_altsetting->desc;
-	struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index];
-	struct usb_device_id *id = &storage_usb_ids[id_index];
+	struct us_unusual_dev *unusual_dev = find_unusual(id);
 
 	/* Store the entries */
 	us->unusual_dev = unusual_dev;
@@ -501,7 +455,7 @@ static void get_device_info(struct us_da
 	us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
 			idesc->bInterfaceProtocol :
 			unusual_dev->useTransport;
-	us->flags = unusual_dev->flags;
+	us->flags = USB_US_ORIG_FLAGS(id->driver_info);
 
 	/*
 	 * This flag is only needed when we're in high-speed, so let's
@@ -529,7 +483,7 @@ static void get_device_info(struct us_da
 		if (unusual_dev->useTransport != US_PR_DEVICE &&
 			us->protocol == idesc->bInterfaceProtocol)
 			msg += 2;
-		if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE))
+		if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
 			printk(KERN_NOTICE USB_STORAGE "This device "
 				"(%04x,%04x,%04x S %02x P %02x)"
 				" has %s in unusual_devs.h\n"
@@ -921,10 +875,12 @@ static int storage_probe(struct usb_inte
 {
 	struct Scsi_Host *host;
 	struct us_data *us;
-	const int id_index = id - storage_usb_ids; 
 	int result;
 	struct task_struct *th;
 
+	if (usb_usual_check_type(id, USB_US_TYPE_STOR))
+		return -ENXIO;
+
 	US_DEBUGP("USB Mass Storage device detected\n");
 
 	/*
@@ -952,12 +908,8 @@ static int storage_probe(struct usb_inte
 
 	/*
 	 * Get the unusual_devs entries and the descriptors
-	 *
-	 * id_index is calculated in the declaration to be the index number
-	 * of the match from the usb_device_id table, so we can find the
-	 * corresponding entry in the private table.
 	 */
-	get_device_info(us, id_index);
+	get_device_info(us, id);
 
 #ifdef CONFIG_USB_STORAGE_SDDR09
 	if (us->protocol == US_PR_EUSB_SDDR09 ||
@@ -1062,9 +1014,10 @@ static int __init usb_stor_init(void)
 
 	/* register the driver, return usb_register return code if error */
 	retval = usb_register(&usb_storage_driver);
-	if (retval == 0)
+	if (retval == 0) {
 		printk(KERN_INFO "USB Mass Storage support registered.\n");
-
+		usb_usual_set_present(USB_US_TYPE_STOR);
+	}
 	return retval;
 }
 
@@ -1088,6 +1041,8 @@ static void __exit usb_stor_exit(void)
 		wait_for_completion(&threads_gone);
 		atomic_dec(&total_threads);
 	}
+
+	usb_usual_clear_present(USB_US_TYPE_STOR);
 }
 
 module_init(usb_stor_init);
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/drivers/usb/storage/usb.h linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/usb.h
--- linux-2.6.14-1.1674_FC5/drivers/usb/storage/usb.h	2005-11-15 12:19:56.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/drivers/usb/storage/usb.h	2005-11-15 13:30:20.000000000 -0800
@@ -45,6 +45,7 @@
 #define _USB_H_
 
 #include <linux/usb.h>
+#include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
@@ -63,38 +64,8 @@ struct us_unusual_dev {
 	__u8  useProtocol;
 	__u8  useTransport;
 	int (*initFunction)(struct us_data *);
-	unsigned int flags;
 };
 
-/*
- * Static flag definitions.  We use this roundabout technique so that the
- * proc_info() routine can automatically display a message for each flag.
- */
-#define US_DO_ALL_FLAGS						\
-	US_FLAG(SINGLE_LUN,	0x00000001)			\
-		/* allow access to only LUN 0 */		\
-	US_FLAG(NEED_OVERRIDE,	0x00000002)			\
-		/* unusual_devs entry is necessary */		\
-	US_FLAG(SCM_MULT_TARG,	0x00000004)			\
-		/* supports multiple targets */			\
-	US_FLAG(FIX_INQUIRY,	0x00000008)			\
-		/* INQUIRY response needs faking */		\
-	US_FLAG(FIX_CAPACITY,	0x00000010)			\
-		/* READ CAPACITY response too big */		\
-	US_FLAG(IGNORE_RESIDUE,	0x00000020)			\
-		/* reported residue is wrong */			\
-	US_FLAG(BULK32,		0x00000040)			\
-		/* Uses 32-byte CBW length */			\
-	US_FLAG(NOT_LOCKABLE,	0x00000080)			\
-		/* PREVENT/ALLOW not supported */		\
-	US_FLAG(GO_SLOW,	0x00000100)			\
-		/* Need delay after Command phase */		\
-	US_FLAG(NO_WP_DETECT,	0x00000200)			\
-		/* Don't check for write-protect */		\
-
-#define US_FLAG(name, value)	US_FL_##name = value ,
-enum { US_DO_ALL_FLAGS };
-#undef US_FLAG
 
 /* Dynamic flag definitions: used in set_bit() etc. */
 #define US_FLIDX_URB_ACTIVE	18  /* 0x00040000  current_urb is in use  */
diff -urpN -X dontdiff linux-2.6.14-1.1674_FC5/include/linux/usb_usual.h linux-2.6.14-1.1674_FC5-ub/include/linux/usb_usual.h
--- linux-2.6.14-1.1674_FC5/include/linux/usb_usual.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.14-1.1674_FC5-ub/include/linux/usb_usual.h	2005-11-15 13:35:50.000000000 -0800
@@ -0,0 +1,123 @@
+/*
+ * Interface to the libusual.
+ *
+ * Copyright (c) 2005 Pete Zaitcev <zaitcev at redhat.com>
+ * Copyright (c) 1999-2002 Matthew Dharm (mdharm-usb at one-eyed-alien.net)
+ * Copyright (c) 1999 Michael Gee (michael at linuxspecific.com)
+ */
+
+#ifndef __LINUX_USB_USUAL_H
+#define __LINUX_USB_USUAL_H
+
+#include <linux/config.h>
+
+/* We should do this for cleanliness... But other usb_foo.h do not do this. */
+/* #include <linux/usb.h> */
+
+/*
+ * The flags field, which we store in usb_device_id.driver_info.
+ * It is compatible with the old usb-storage flags in lower 24 bits.
+ */
+
+/*
+ * Static flag definitions.  We use this roundabout technique so that the
+ * proc_info() routine can automatically display a message for each flag.
+ */
+#define US_DO_ALL_FLAGS						\
+	US_FLAG(SINGLE_LUN,	0x00000001)			\
+		/* allow access to only LUN 0 */		\
+	US_FLAG(NEED_OVERRIDE,	0x00000002)			\
+		/* unusual_devs entry is necessary */		\
+	US_FLAG(SCM_MULT_TARG,	0x00000004)			\
+		/* supports multiple targets */			\
+	US_FLAG(FIX_INQUIRY,	0x00000008)			\
+		/* INQUIRY response needs faking */		\
+	US_FLAG(FIX_CAPACITY,	0x00000010)			\
+		/* READ CAPACITY response too big */		\
+	US_FLAG(IGNORE_RESIDUE,	0x00000020)			\
+		/* reported residue is wrong */			\
+	US_FLAG(BULK32,		0x00000040)			\
+		/* Uses 32-byte CBW length */			\
+	US_FLAG(NOT_LOCKABLE,	0x00000080)			\
+		/* PREVENT/ALLOW not supported */		\
+	US_FLAG(GO_SLOW,	0x00000100)			\
+		/* Need delay after Command phase */		\
+	US_FLAG(NO_WP_DETECT,	0x00000200)			\
+		/* Don't check for write-protect */		\
+
+#define US_FLAG(name, value)	US_FL_##name = value ,
+enum { US_DO_ALL_FLAGS };
+#undef US_FLAG
+
+/*
+ * The bias field for libusual and friends.
+ */
+#define USB_US_TYPE_NONE   0
+#define USB_US_TYPE_STOR   1		/* usb-storage */
+#define USB_US_TYPE_UB     2		/* ub */
+
+#define USB_US_TYPE(flags) 		(((flags) >> 24) & 0xFF)
+#define USB_US_ORIG_FLAGS(flags)	((flags) & 0x00FFFFFF)
+
+/*
+ * This is probably not the best place to keep these constants, conceptually.
+ * But it's the only header included into all places which need them.
+ */
+
+/* Sub Classes */
+
+#define US_SC_RBC	0x01		/* Typically, flash devices */
+#define US_SC_8020	0x02		/* CD-ROM */
+#define US_SC_QIC	0x03		/* QIC-157 Tapes */
+#define US_SC_UFI	0x04		/* Floppy */
+#define US_SC_8070	0x05		/* Removable media */
+#define US_SC_SCSI	0x06		/* Transparent */
+#define US_SC_ISD200    0x07		/* ISD200 ATA */
+#define US_SC_MIN	US_SC_RBC
+#define US_SC_MAX	US_SC_ISD200
+
+#define US_SC_DEVICE	0xff		/* Use device's value */
+
+/* Protocols */
+
+#define US_PR_CBI	0x00		/* Control/Bulk/Interrupt */
+#define US_PR_CB	0x01		/* Control/Bulk w/o interrupt */
+#define US_PR_BULK	0x50		/* bulk only */
+#ifdef CONFIG_USB_STORAGE_USBAT
+#define US_PR_USBAT	0x80		/* SCM-ATAPI bridge */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR09
+#define US_PR_EUSB_SDDR09	0x81	/* SCM-SCSI bridge for SDDR-09 */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR55
+#define US_PR_SDDR55	0x82		/* SDDR-55 (made up) */
+#endif
+#define US_PR_DPCM_USB  0xf0		/* Combination CB/SDDR09 */
+#ifdef CONFIG_USB_STORAGE_FREECOM
+#define US_PR_FREECOM   0xf1		/* Freecom */
+#endif
+#ifdef CONFIG_USB_STORAGE_DATAFAB
+#define US_PR_DATAFAB   0xf2		/* Datafab chipsets */
+#endif
+#ifdef CONFIG_USB_STORAGE_JUMPSHOT
+#define US_PR_JUMPSHOT  0xf3		/* Lexar Jumpshot */
+#endif
+
+#define US_PR_DEVICE	0xff		/* Use device's value */
+
+/*
+ */
+#ifdef CONFIG_USB_LIBUSUAL
+
+extern struct usb_device_id storage_usb_ids[];
+extern void usb_usual_set_present(int type);
+extern void usb_usual_clear_present(int type);
+extern int usb_usual_check_type(const struct usb_device_id *, int type);
+#else
+
+#define usb_usual_set_present(t)	do { } while(0)
+#define usb_usual_clear_present(t)	do { } while(0)
+#define usb_usual_check_type(id, t)	(0)
+#endif /* CONFIG_USB_LIBUSUAL */
+
+#endif /* __LINUX_USB_USUAL_H */

--- linux-2.6.14/drivers/usb/Makefile~	2005-11-15 21:51:46.000000000 -0500
+++ linux-2.6.14/drivers/usb/Makefile	2005-11-15 21:52:24.000000000 -0500
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_MIDI)		+= class/
 obj-$(CONFIG_USB_PRINTER)	+= class/
 
 obj-$(CONFIG_USB_STORAGE)	+= storage/
+obj-$(CONFIG_USB)		+= storage/
 
 obj-$(CONFIG_USB_AIPTEK)	+= input/
 obj-$(CONFIG_USB_ATI_REMOTE)	+= input/

linux-2.6-unexport-symbols.patch:
 arch/x86_64/ia32/sys_ia32.c |    1 -
 fs/open.c                   |    1 -
 2 files changed, 2 deletions(-)

--- NEW FILE linux-2.6-unexport-symbols.patch ---
No external modules should be touching these symbols.
If they are, they are broken.

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/fs/open.c linux-10000/fs/open.c
--- linux-3022/fs/open.c
+++ linux-10000/fs/open.c
@@ -976,7 +976,6 @@ out_error:
 	fd = error;
 	goto out;
 }
-EXPORT_SYMBOL_GPL(sys_open);
 
 #ifndef __alpha__
 
diff -urNp --exclude-from=/home/davej/.exclude linux-3022/arch/x86_64/ia32/sys_ia32.c linux-10000/arch/x86_64/ia32/sys_ia32.c
--- linux-3022/arch/x86_64/ia32/sys_ia32.c
+++ linux-10000/arch/x86_64/ia32/sys_ia32.c
@@ -1048,4 +1048,3 @@ static int __init ia32_init (void)
 __initcall(ia32_init);
 
 extern unsigned long ia32_sys_call_table[];
-EXPORT_SYMBOL(ia32_sys_call_table);

linux-2.6-valid-ether-addr.patch:
 etherdevice.h |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6-valid-ether-addr.patch ---
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -91,9 +91,8 @@ static inline int is_broadcast_ether_add
  */
 static inline int is_valid_ether_addr(const u8 *addr)
 {
-	/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
-	 * explicitly check for it here. */
-	return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
+	return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr) &&
+	       !is_broadcast_ether_addr(addr);
 }
 
 /**

linux-2.6-vdso-xen.patch:
 mmu.h  |    1 +
 page.h |    5 +++++
 2 files changed, 6 insertions(+)

--- NEW FILE linux-2.6-vdso-xen.patch ---
Merge rawhide vdso into xen-specific subarch.
---

 include/asm-i386/mach-xen/asm/mmu.h  |    1 +
 include/asm-i386/mach-xen/asm/page.h |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/include/asm-i386/mach-xen/asm/mmu.h b/include/asm-i386/mach-xen/asm/mmu.h
index 32987b8..c646692 100644
--- a/include/asm-i386/mach-xen/asm/mmu.h
+++ b/include/asm-i386/mach-xen/asm/mmu.h
@@ -12,6 +12,7 @@ typedef struct { 
 	int size;
 	struct semaphore sem;
 	void *ldt;
+	void *vdso;
 } mm_context_t;
 
 /* mm/memory.c:exit_mmap hook */
diff --git a/include/asm-i386/mach-xen/asm/page.h b/include/asm-i386/mach-xen/asm/page.h
index 74b385b..21f8300 100644
--- a/include/asm-i386/mach-xen/asm/page.h
+++ b/include/asm-i386/mach-xen/asm/page.h
@@ -237,6 +237,11 @@ extern int page_is_ram(unsigned long pag
 #undef LOAD_OFFSET
 #define LOAD_OFFSET		0
 
+/*
+ * Under exec-shield we don't use the generic fixmap gate area.
+ * The vDSO ("gate area") has a normal vma found the normal ways.
+ */
+#define __HAVE_ARCH_GATE_AREA  1
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)

linux-2.6-vm-oomkiller-debugging.patch:
 oom_kill.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6-vm-oomkiller-debugging.patch ---
--- linux-2.6.12/mm/oom_kill.c~	2005-06-22 14:16:57.000000000 -0400
+++ linux-2.6.12/mm/oom_kill.c	2005-06-22 14:17:35.000000000 -0400
@@ -272,6 +272,7 @@ retry:
 	/* Found nothing?!?! Either we hang forever, or we panic. */
 	if (!p) {
 		read_unlock(&tasklist_lock);
+		show_mem();
 		panic("Out of memory and no killable processes...\n");
 	}
 

linux-2.6-vm-silence-atomic-alloc-failures.patch:
 gfp.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-vm-silence-atomic-alloc-failures.patch ---
Atomic failures aren't too interesting.

diff -urNp --exclude-from=/home/davej/.exclude linux-3022/include/linux/gfp.h linux-10000/include/linux/gfp.h
--- linux-3022/include/linux/gfp.h
+++ linux-10000/include/linux/gfp.h
@@ -47,7 +47,7 @@ struct vm_area_struct;
 			__GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \
 			__GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP)
 
-#define GFP_ATOMIC	(__GFP_HIGH)
+#define GFP_ATOMIC	(__GFP_HIGH | __GFP_NOWARN)
 #define GFP_NOIO	(__GFP_WAIT)
 #define GFP_NOFS	(__GFP_WAIT | __GFP_IO)
 #define GFP_KERNEL	(__GFP_WAIT | __GFP_IO | __GFP_FS)

linux-2.6-write-protect-rodata.patch:
 linux-2.6.14-fordiff/arch/i386/Kconfig.debug           |   10 +++++++
 linux-2.6.14-fordiff/arch/i386/kernel/entry.S          |    1 
 linux-2.6.14-fordiff/arch/i386/kernel/syscall_table.S  |    1 
 linux-2.6.14-fordiff/arch/i386/mm/init.c               |   24 +++++++++++++++++
 linux-2.6.14-fordiff/arch/x86_64/Kconfig.debug         |   10 +++++++
 linux-2.6.14-fordiff/arch/x86_64/kernel/syscall.c      |    2 -
 linux-2.6.14-fordiff/arch/x86_64/mm/init.c             |   23 ++++++++++++++++
 linux-2.6.14-fordiff/arch/x86_64/mm/pageattr.c         |    9 ++++--
 linux-2.6.14-fordiff/include/asm-generic/vmlinux.lds.h |    4 ++
 linux-2.6.14-fordiff/include/asm-x86_64/pgtable.h      |    2 +
 linux-2.6.14-fordiff/init/main.c                       |    6 ++++
 linux-2.6.14/arch/i386/mm/init.c                       |   12 ++++++++
 linux-2.6.14/arch/x86_64/ia32/ia32entry.S              |    2 -
 linux-2.6.14/arch/x86_64/mm/init.c                     |   12 ++++++++
 linux-2.6.9-22.EL/arch/i386/mm/pageattr.c              |   23 ++++++++++++----
 15 files changed, 131 insertions(+), 10 deletions(-)

--- NEW FILE linux-2.6-write-protect-rodata.patch ---

I've been working on a patch that turns the kernel's .rodata section to be
actually read only, eg any write attempts to it cause a segmentation fault.
During this work I found a bug in the change_page_attr() code on x86-64, and
this patch 1 is the bugfix for that. Patch 2 will be the actual introduction
of the readonly option.

The bug fixed here is the following: when splitting a 2Mb PSE page that also
happened to contain kernel text, the split PMD would get the NX bit set
eventhough the individual pte entries for the 4Kb pages would not. This
causes problems still since this NX bit overrides in practice the sub bits.
The solution I've chosen is I think the right one: On splitting a 2Mb page
in the change_page_attr() code, inherit the existing pagetable permissions
exactly, for both the PMD page and all the 4Kb pte entries (with the
exception of the one that you wanted to change, but the code already did
that part correct).

Signed-off-by: Arjan van de Ven <arjan at infradead.org>

diff -purN linux-2.6.14/arch/x86_64/mm/pageattr.c linux-2.6.14-fordiff/arch/x86_64/mm/pageattr.c
--- linux-2.6.14/arch/x86_64/mm/pageattr.c	2005-10-28 02:02:08.000000000 +0200
+++ linux-2.6.14-fordiff/arch/x86_64/mm/pageattr.c	2005-11-08 17:17:10.000000000 +0100
@@ -128,6 +128,7 @@ __change_page_attr(unsigned long address
 	pte_t *kpte; 
 	struct page *kpte_page;
 	unsigned kpte_flags;
+	pgprot_t ref_prot2;
 	kpte = lookup_address(address);
 	if (!kpte) return 0;
 	kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
@@ -140,10 +141,14 @@ __change_page_attr(unsigned long address
  			 * split_large_page will take the reference for this change_page_attr
  			 * on the split page.
  			 */
-			struct page *split = split_large_page(address, prot, ref_prot); 
+
+			struct page *split;
+			ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE));
+
+			split = split_large_page(address, prot, ref_prot2);
 			if (!split)
 				return -ENOMEM;
-			set_pte(kpte,mk_pte(split, ref_prot));
+			set_pte(kpte,mk_pte(split, ref_prot2));
 			kpte_page = split;
 		}	
 		get_page(kpte_page);
diff -purN linux-2.6.14/include/asm-x86_64/pgtable.h linux-2.6.14-fordiff/include/asm-x86_64/pgtable.h
--- linux-2.6.14/include/asm-x86_64/pgtable.h	2005-11-08 10:56:54.000000000 +0100
+++ linux-2.6.14-fordiff/include/asm-x86_64/pgtable.h	2005-11-08 17:17:10.000000000 +0100
@@ -122,6 +122,8 @@ static inline pte_t ptep_get_and_clear_f
 
 #define pte_same(a, b)		((a).pte == (b).pte)
 
+#define pte_pgprot(a)	(__pgprot((a).pte & ~PHYSICAL_PAGE_MASK))
+
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
 #define PUD_SIZE	(1UL << PUD_SHIFT)





This patch introduces the actual debug option to catch any writes to rodata

Signed-off-by: Arjan van de Ven <arjan at infradead.org>


diff -purN linux-2.6.14/arch/i386/Kconfig.debug linux-2.6.14-fordiff/arch/i386/Kconfig.debug
--- linux-2.6.14/arch/i386/Kconfig.debug	2005-11-08 10:56:47.000000000 +0100
+++ linux-2.6.14-fordiff/arch/i386/Kconfig.debug	2005-11-08 17:19:23.000000000 +0100
@@ -42,6 +42,16 @@ config DEBUG_PAGEALLOC
 	  This results in a large slowdown, but helps to find certain types
 	  of memory corruptions.
 
+config DEBUG_RODATA
+	bool "Write protect kernel read-only data structures"
+	depends on DEBUG_KERNEL
+	help
+	  Mark the kernel read-only data as write-protected in the pagetables,
+	  in order to catch accidental (and incorrect) writes to such const
+	  data. This option may have a slight performance impact because a
+	  portion of the kernel code won't be covered by a 2MB TLB anymore.
+	  If in doubt, say "N".
+
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	depends on DEBUG_KERNEL
diff -purN linux-2.6.14/arch/i386/kernel/entry.S linux-2.6.14-fordiff/arch/i386/kernel/entry.S
--- linux-2.6.14/arch/i386/kernel/entry.S	2005-11-08 10:56:47.000000000 +0100
+++ linux-2.6.14-fordiff/arch/i386/kernel/entry.S	2005-11-08 18:29:37.000000000 +0100
@@ -676,6 +676,7 @@ ENTRY(spurious_interrupt_bug)
 	pushl $do_spurious_interrupt_bug
 	jmp error_code
 
+.section .rodata,"a"
 #include "syscall_table.S"
 
 syscall_table_size=(.-sys_call_table)
diff -purN linux-2.6.14/arch/i386/kernel/syscall_table.S linux-2.6.14-fordiff/arch/i386/kernel/syscall_table.S
--- linux-2.6.14/arch/i386/kernel/syscall_table.S	2005-11-08 10:56:47.000000000 +0100
+++ linux-2.6.14-fordiff/arch/i386/kernel/syscall_table.S	2005-11-08 18:29:14.000000000 +0100
@@ -1,4 +1,3 @@
-.data
 ENTRY(sys_call_table)
 	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
 	.long sys_exit
diff -purN linux-2.6.14/arch/i386/mm/init.c linux-2.6.14-fordiff/arch/i386/mm/init.c
--- linux-2.6.14/arch/i386/mm/init.c	2005-11-08 10:56:47.000000000 +0100
+++ linux-2.6.14-fordiff/arch/i386/mm/init.c	2005-11-08 17:17:10.000000000 +0100
@@ -734,6 +734,30 @@ void free_initmem(void)
 	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
 }
 
+#ifdef CONFIG_DEBUG_RODATA
+
+extern char __start_rodata, __end_rodata;
+void mark_rodata_ro(void)
+{
+	unsigned long addr = (unsigned long)&__start_rodata;
+
+	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
+		change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO);
+
+	printk ("Write protecting the kernel read-only data: %luk\n",
+			(&__end_rodata - &__start_rodata) >> 10);
+
+	/*
+	 * change_page_attr() requires a global_flush_tlb() call after it.
+	 * We do this after the printk so that if something went wrong in the
+	 * change, the printk gets out at least to give a better debug hint
+	 * of who is the culprit.
+	 */
+	global_flush_tlb();
+}
+#endif
+
+
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
diff -purN linux-2.6.14/arch/x86_64/Kconfig.debug linux-2.6.14-fordiff/arch/x86_64/Kconfig.debug
--- linux-2.6.14/arch/x86_64/Kconfig.debug	2005-11-08 10:56:48.000000000 +0100
+++ linux-2.6.14-fordiff/arch/x86_64/Kconfig.debug	2005-11-08 17:18:32.000000000 +0100
@@ -9,6 +9,16 @@ config INIT_DEBUG
 	  Fill __init and __initdata at the end of boot. This helps debugging
 	  illegal uses of __init and __initdata after initialization.
 
+config DEBUG_RODATA
+       bool "Write protect kernel read-only data structures"
+       depends on DEBUG_KERNEL
+       help
+	 Mark the kernel read-only data as write-protected in the pagetables,
+	 in order to catch accidental (and incorrect) writes to such const data.
+	 This option may have a slight performance impact because a portion
+	 of the kernel code won't be covered by a 2MB TLB anymore.
+	 If in doubt, say "N".
+
 config IOMMU_DEBUG
        depends on GART_IOMMU && DEBUG_KERNEL
        bool "Enable IOMMU debugging"
diff -purN linux-2.6.14/arch/x86_64/kernel/syscall.c linux-2.6.14-fordiff/arch/x86_64/kernel/syscall.c
--- linux-2.6.14/arch/x86_64/kernel/syscall.c	2005-10-28 02:02:08.000000000 +0200
+++ linux-2.6.14-fordiff/arch/x86_64/kernel/syscall.c	2005-11-08 18:28:25.000000000 +0100
@@ -19,7 +19,7 @@ typedef void (*sys_call_ptr_t)(void); 
 
 extern void sys_ni_syscall(void);
 
-sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = { 
+const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { 
 	/* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ 
 	[0 ... __NR_syscall_max] = &sys_ni_syscall,
 #include <asm-x86_64/unistd.h>
diff -purN linux-2.6.14/arch/x86_64/mm/init.c linux-2.6.14-fordiff/arch/x86_64/mm/init.c
--- linux-2.6.14/arch/x86_64/mm/init.c	2005-11-08 10:56:48.000000000 +0100
+++ linux-2.6.14-fordiff/arch/x86_64/mm/init.c	2005-11-08 17:17:10.000000000 +0100
@@ -498,6 +498,29 @@ void free_initmem(void)
 	printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10);
 }
 
+#ifdef CONFIG_DEBUG_RODATA
+
+extern char __start_rodata, __end_rodata;
+void mark_rodata_ro(void)
+{
+	unsigned long addr = (unsigned long)&__start_rodata;
+
+	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
+		change_page_attr_addr(addr, 1, PAGE_KERNEL_RO);
+
+	printk ("Write protecting the kernel read-only data: %luk\n",
+			(&__end_rodata - &__start_rodata) >> 10);
+
+	/*
+	 * change_page_attr_addr() requires a global_flush_tlb() call after it.
+	 * We do this after the printk so that if something went wrong in the
+	 * change, the printk gets out at least to give a better debug hint
+	 * of who is the culprit.
+	 */
+	global_flush_tlb();
+}
+#endif
+
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
diff -purN linux-2.6.14/include/asm-generic/vmlinux.lds.h linux-2.6.14-fordiff/include/asm-generic/vmlinux.lds.h
--- linux-2.6.14/include/asm-generic/vmlinux.lds.h	2005-11-08 10:56:51.000000000 +0100
+++ linux-2.6.14-fordiff/include/asm-generic/vmlinux.lds.h	2005-11-08 17:19:59.000000000 +0100
@@ -10,6 +10,8 @@
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
 #define RODATA								\
+	. = ALIGN(4096);						\
+	__start_rodata = .;						\
 	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
 		*(.rodata) *(.rodata.*)					\
 		*(__vermagic)		/* Kernel version magic */	\
@@ -74,6 +76,8 @@
         __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
 		*(__ksymtab_strings)					\
 	}								\
+	__end_rodata = .;						\
+	. = ALIGN(4096);						\
 									\
 	/* Built-in module parameters. */				\
 	__param : AT(ADDR(__param) - LOAD_OFFSET) {			\
diff -purN linux-2.6.14/init/main.c linux-2.6.14-fordiff/init/main.c
--- linux-2.6.14/init/main.c	2005-11-08 10:56:54.000000000 +0100
+++ linux-2.6.14-fordiff/init/main.c	2005-11-08 17:17:10.000000000 +0100
@@ -100,6 +100,11 @@ extern void acpi_early_init(void);
 #else
 static inline void acpi_early_init(void) { }
 #endif
+#ifdef CONFIG_DEBUG_RODATA
+extern void mark_rodata_ro(void);
+#else
+static inline void mark_rodata_ro(void) { }
+#endif
 
 #ifdef CONFIG_TC
 extern void tc_init(void);
@@ -713,6 +718,7 @@ static int init(void * unused)
 	 */
 	free_initmem();
 	unlock_kernel();
+	mark_rodata_ro();
 	system_state = SYSTEM_RUNNING;
 	numa_default_policy();
 

--- linux-2.6.14/arch/i386/mm/init.c~	2005-11-22 10:05:02.000000000 -0500
+++ linux-2.6.14/arch/i386/mm/init.c	2005-11-22 10:08:07.000000000 -0500
@@ -809,10 +809,14 @@ void free_initmem(void)
 
 #ifdef CONFIG_DEBUG_RODATA
 
+static int nowprodata;
+
 extern char __start_rodata, __end_rodata;
 void mark_rodata_ro(void)
 {
 	unsigned long addr = (unsigned long)&__start_rodata;
+	if (nowprodata == 1)
+		return;
 
 	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
 		change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO);
@@ -828,6 +832,14 @@ void mark_rodata_ro(void)
 	 */
 	global_flush_tlb();
 }
+ 
+static int __init disable_rodata(char *str)
+{
+	nowprodata = 1;
+	return 1;
+}
+__setup("nowprodata", disable_rodata);
+
 #endif
 
 
--- linux-2.6.14/arch/x86_64/mm/init.c~	2005-11-22 10:11:34.000000000 -0500
+++ linux-2.6.14/arch/x86_64/mm/init.c	2005-11-22 10:14:00.000000000 -0500
@@ -576,11 +576,16 @@ void free_initmem(void)
 
 #ifdef CONFIG_DEBUG_RODATA
 
+static int nowprodata;
+
 extern char __start_rodata, __end_rodata;
 void mark_rodata_ro(void)
 {
 	unsigned long addr = (unsigned long)&__start_rodata;
 
+	if (nowprodata == 1)
+		return;
+
 	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
 		change_page_attr_addr(addr, 1, PAGE_KERNEL_RO);
 
@@ -595,6 +600,13 @@ void mark_rodata_ro(void)
 	 */
 	global_flush_tlb();
 }
+
+static int __init disable_rodata(char *str)
+{
+	nowprodata = 1;
+	return 1;
+}
+__setup("nowprodata", disable_rodata);
 #endif
 
 #ifdef CONFIG_BLK_DEV_INITRD




--- linux-2.6.9-22.EL/arch/i386/mm/pageattr.c.nopatch	2005-10-04 10:33:12.000000000 -0500
+++ linux-2.6.9-22.EL/arch/i386/mm/pageattr.c	2005-10-04 10:33:33.000000000 -0500
@@ -31,7 +31,8 @@ pte_t *lookup_address(unsigned long addr
         return pte_offset_kernel(pmd, address);
 } 
 
-static struct page *split_large_page(unsigned long address, pgprot_t prot)
+static struct page *split_large_page(unsigned long address, pgprot_t prot,
+					pgprot_t ref_prot)
 { 
 	int i; 
 	unsigned long addr;
@@ -54,7 +54,7 @@ static struct page *split_large_page(uns
 	pbase = (pte_t *)page_address(base);
 	for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
                set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT,
-                                          addr == address ? prot : PAGE_KERNEL));
+                                          addr == address ? prot : ref_prot));
 	}
 	return base;
 } 
@@ -98,11 +98,17 @@ static void set_pmd_pte(pte_t *kpte, uns
  */
 static inline void revert_page(struct page *kpte_page, unsigned long address)
 {
+	pgprot_t ref_prot;
+
+	ref_prot =
+	((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
+		? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
+
 	pte_t *linear = (pte_t *) 
 		pmd_offset(pud_offset(pgd_offset_k(address), address), address);
 	set_pmd_pte(linear,  address,
 		    pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
-			    PAGE_KERNEL_LARGE));
+			    ref_prot));
 }
 
 static int
@@ -121,10 +128,16 @@ __change_page_attr(struct page *page, pg
 		if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
 			set_pte_atomic(kpte, mk_pte(page, prot)); 
 		} else {
-			struct page *split = split_large_page(address, prot); 
+			pgprot_t ref_prot;
+			struct page *split;
+	
+			ref_prot =
+			((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
+				? PAGE_KERNEL_EXEC : PAGE_KERNEL;
+			split = split_large_page(address, prot, ref_prot); 
 			if (!split)
 				return -ENOMEM;
-			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+			set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
 			kpte_page = split;
 		}	
 		get_page(kpte_page);
--- linux-2.6.14/arch/x86_64/ia32/ia32entry.S~	2005-12-01 12:25:15.000000000 -0500
+++ linux-2.6.14/arch/x86_64/ia32/ia32entry.S	2005-12-01 12:25:30.000000000 -0500
@@ -341,7 +341,7 @@ ENTRY(ia32_ptregs_common)
 	jmp  ia32_sysret	/* misbalances the return cache */
 	CFI_ENDPROC
 
-	.data
+	.section .rodata,"a"
 	.align 8
 	.globl ia32_sys_call_table
 ia32_sys_call_table:

linux-2.6-x86-apic-off-by-default.patch:
 arch/i386/Kconfig            |   12 ++++++++++++
 arch/i386/kernel/acpi/boot.c |   13 +++++++++++++
 arch/i386/kernel/apic.c      |   13 ++++++++++---
 arch/i386/kernel/io_apic.c   |    2 +-
 arch/i386/kernel/setup.c     |   18 ++++++++++++++++--
 include/asm-i386/acpi.h      |    4 ++++
 include/asm-i386/apic.h      |    6 ++++++
 7 files changed, 62 insertions(+), 6 deletions(-)

--- NEW FILE linux-2.6-x86-apic-off-by-default.patch ---
diff -Naur orig/arch/i386/Kconfig new/arch/i386/Kconfig
--- orig/arch/i386/Kconfig	2005-11-22 13:32:50.000000000 -0800
+++ new/arch/i386/Kconfig	2005-11-22 13:34:28.000000000 -0800
@@ -253,6 +253,18 @@
 	  to use it. If you say Y here even though your machine doesn't have
 	  an IO-APIC, then the kernel will still run with no slowdown at all.
 
+config X86_UP_APIC_DEFAULT_OFF
+	bool "APIC support on uniprocessors defaults to off"
+	depends on !SMP && X86_UP_APIC
+	help
+	  Some older systems have flaky APICs.  Say Y to turn off APIC
+	  support by default, while still allowing it to be enabled by the
+	  "lapic" and "apic" command line options.
+
+	  Usually this is only necessary for distro installer kernels that
+	  must work with everything.  Everyone else can safely say N here
+	  and configure APIC support in or out as needed.
+
 config X86_LOCAL_APIC
 	bool
 	depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER)
diff -Naur orig/arch/i386/kernel/acpi/boot.c new/arch/i386/kernel/acpi/boot.c
--- orig/arch/i386/kernel/acpi/boot.c	2005-11-22 13:32:50.000000000 -0800
+++ new/arch/i386/kernel/acpi/boot.c	2005-11-23 12:53:56.000000000 -0800
@@ -37,6 +37,10 @@
 #include <asm/io.h>
 #include <asm/mpspec.h>
 
+#ifdef CONFIG_X86_32
+extern int enable_local_apic __initdata;
+#endif
+
 #ifdef	CONFIG_X86_64
 
 extern void __init clustered_apic_check(void);
@@ -800,6 +804,15 @@
 #ifdef CONFIG_X86_LOCAL_APIC
 	int count, error;
 
+#ifdef CONFIG_X86_32
+	if (enable_local_apic < 0) {
+		printk(KERN_INFO PREFIX "Local APIC disabled (%d); pass 'lapic' to re-enable.\n", enable_local_apic);
+		return;
+	}
+
+	printk(KERN_INFO PREFIX "Local APIC enabled (%d).\n", enable_local_apic);
+#endif
+
 	count = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
 	if (count >= 1) {
 
diff -Naur orig/arch/i386/kernel/apic.c new/arch/i386/kernel/apic.c
--- orig/arch/i386/kernel/apic.c	2005-11-22 13:32:46.000000000 -0800
+++ new/arch/i386/kernel/apic.c	2005-11-22 18:06:18.000000000 -0800
@@ -42,8 +42,9 @@
 
 /*
  * Knob to control our willingness to enable the local APIC.
+ * -2=default-disable, -1=force-disable, 1=force-enable, 0=automatic
  */
-int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+int enable_local_apic __initdata = (X86_APIC_DEFAULT_OFF ? -2 : 0);
 
 /*
  * Debug level
@@ -757,7 +758,7 @@
 		 * APIC only if "lapic" specified.
 		 */
 		if (enable_local_apic <= 0) {
-			printk("Local APIC disabled by BIOS -- "
+			printk("Local APIC disabled by BIOS (or by default) -- "
 			       "you can enable it with \"lapic\"\n");
 			return -1;
 		}
@@ -839,7 +840,7 @@
 		int i;
 
 		for (i = 0; i < nr_ioapics; i++) {
-			if (smp_found_config) {
+			if (smp_found_config && !skip_ioapic_setup) {
 				ioapic_phys = mp_ioapics[i].mpc_apicaddr;
 				if (!ioapic_phys) {
 					printk(KERN_ERR
@@ -1272,6 +1273,12 @@
 	if (!smp_found_config && !cpu_has_apic)
 		return -1;
 
+	/* if local apic is off due to config_x86_apic_off option, jump out here */
+	if (enable_local_apic < -1) {
+		printk(KERN_INFO "Local APIC disabled by default; use 'lapic' to enable it.\n");
+		return -1;
+	}
+
 	/*
 	 * Complain if the BIOS pretends there is one.
 	 */
diff -Naur orig/arch/i386/kernel/io_apic.c new/arch/i386/kernel/io_apic.c
--- orig/arch/i386/kernel/io_apic.c	2005-11-22 13:32:46.000000000 -0800
+++ new/arch/i386/kernel/io_apic.c	2005-11-22 13:34:27.000000000 -0800
@@ -681,7 +681,7 @@
 #define MAX_PIRQS 8
 static int pirq_entries [MAX_PIRQS];
 static int pirqs_enabled;
-int skip_ioapic_setup;
+int skip_ioapic_setup = X86_APIC_DEFAULT_OFF;
 
 static int __init ioapic_setup(char *str)
 {
diff -Naur orig/arch/i386/kernel/setup.c new/arch/i386/kernel/setup.c
--- orig/arch/i386/kernel/setup.c	2005-11-22 13:32:46.000000000 -0800
+++ new/arch/i386/kernel/setup.c	2005-11-23 01:29:18.000000000 -0800
@@ -60,6 +60,10 @@
 #include "setup_arch_pre.h"
 #include <bios_ebda.h>
 
+#ifdef CONFIG_X86_LOCAL_APIC
+extern int enable_local_apic __initdata;
+#endif
+
 /* Forward Declaration. */
 void __init find_max_pfn(void);
 
@@ -865,6 +869,10 @@
 		/* disable IO-APIC */
 		else if (!memcmp(from, "noapic", 6))
 			disable_ioapic_setup();
+		/* disable IO-APIC */
+		else if (!memcmp(from, "apic", 4))
+			enable_ioapic_setup();
+
 #endif /* CONFIG_X86_IO_APIC */
 #endif /* CONFIG_ACPI */
 
@@ -1606,8 +1614,14 @@
 #endif
 #endif
 #ifdef CONFIG_X86_LOCAL_APIC
-	if (smp_found_config)
-		get_smp_config();
+	if (smp_found_config) {
+		if (enable_local_apic >= 0) {
+			printk(KERN_INFO "LAPIC enabled (%d), calling get_smp_config\n", enable_local_apic);
+			get_smp_config();
+		} else {
+			printk(KERN_INFO "LAPIC disabled (%d)\n", enable_local_apic);
+		}
+	}
 #endif
 
 	register_memory();
diff -Naur orig/include/asm-i386/acpi.h new/include/asm-i386/acpi.h
--- orig/include/asm-i386/acpi.h	2005-10-27 17:02:08.000000000 -0700
+++ new/include/asm-i386/acpi.h	2005-11-22 13:34:27.000000000 -0800
@@ -134,6 +134,10 @@
 {
 	skip_ioapic_setup = 1;
 }
+static inline void enable_ioapic_setup(void)
+{
+	skip_ioapic_setup = 0;
+}
 
 static inline int ioapic_setup_disabled(void)
 {
diff -Naur orig/include/asm-i386/apic.h new/include/asm-i386/apic.h
--- orig/include/asm-i386/apic.h	2005-10-27 17:02:08.000000000 -0700
+++ new/include/asm-i386/apic.h	2005-11-22 13:34:27.000000000 -0800
@@ -82,6 +82,12 @@
 # define apic_write_around(x,y) apic_write_atomic((x),(y))
 #endif
 
+#ifdef CONFIG_X86_UP_APIC_DEFAULT_OFF
+# define X86_APIC_DEFAULT_OFF 1
+#else
+# define X86_APIC_DEFAULT_OFF 0
+#endif
+
 static inline void ack_APIC_irq(void)
 {
 	/*

linux-2.6-x86-tune-p4.patch:
 linux-2.6.10/arch/i386/Makefile.cpu |    2 +-
 linux-2.6.12/arch/x86_64/Makefile   |    4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

--- NEW FILE linux-2.6-x86-tune-p4.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1/arch/i386/Makefile linux-212/arch/i386/Makefile
--- linux-2.6.10/arch/i386/Makefile.cpu
+++ linux-2.6.10/arch/i386/Makefile.cpu
@@ -33,7 +33,7 @@ cflags-$(CONFIG_M486)		+= -march=i486
 cflags-$(CONFIG_M586)		+= -march=i586
 cflags-$(CONFIG_M586TSC)	+= -march=i586
 cflags-$(CONFIG_M586MMX)	+= $(call cc-option,-march=pentium-mmx,-march=i586)
-cflags-$(CONFIG_M686)		+= -march=i686
+cflags-$(CONFIG_M686)		+= -march=i686 $(call tune,pentium4)
 cflags-$(CONFIG_MPENTIUMII)	+= -march=i686 $(call tune,pentium2)
 cflags-$(CONFIG_MPENTIUMIII)	+= -march=i686 $(call tune,pentium3)
 cflags-$(CONFIG_MPENTIUMM)	+= -march=i686 $(call tune,pentium3)
--- linux-2.6.12/arch/x86_64/Makefile~	2005-07-05 19:48:18.000000000 -0400
+++ linux-2.6.12/arch/x86_64/Makefile	2005-07-05 19:49:06.000000000 -0400
@@ -39,9 +39,7 @@ LDFLAGS_vmlinux :=
 
 CHECKFLAGS      += -D__x86_64__ -m64
 
-cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
-cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
-CFLAGS += $(cflags-y)
+CFLAGS += -march=k8 -mtune=nocona
 
 CFLAGS += -mno-red-zone
 CFLAGS += -mcmodel=kernel

linux-2.6-x86-vga-vidfail.patch:
 video.S |    4 ++++
 1 files changed, 4 insertions(+)

--- NEW FILE linux-2.6-x86-vga-vidfail.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-910/arch/i386/boot/video.S linux-1000/arch/i386/boot/video.S
--- linux-910/arch/i386/boot/video.S
+++ linux-1000/arch/i386/boot/video.S
@@ -126,8 +126,12 @@ video:	pushw	%ds		# We use different seg
 	call	mode_set			# Set the mode
 	jc	vid1
 
+#if 0
 	leaw	badmdt, %si			# Invalid mode ID
 	call	prtstr
+#else
+	jmp	vid1
+#endif /* CONFIG_VIDEO_IGNORE_BAD_MODE */
 vid2:	call	mode_menu
 vid1:
 #ifdef CONFIG_VIDEO_RETAIN

linux-2.6-xen-additional.patch:
 linux-2.6.10/include/asm-x86_64/hw_irq.h                |    3 
 linux-2.6.10/include/asm-x86_64/irq.h                   |    5 
 linux-2.6.10/include/asm-x86_64/posix_types.h           |    4 
 linux-2.6.11-rcu/kernel/rcupdate.c                      |    5 
 linux-2.6.12.new/arch/i386/mm/init.c                    |    2 
 linux-2.6.12.new/arch/i386/mm/pageattr.c                |    2 
 linux-2.6.12.new/arch/i386/mm/pgtable.c                 |   40 ++++++-
 linux-2.6.12.new/include/asm-i386/pgtable-2level-defs.h |    2 
 linux-2.6.12.new/include/asm-i386/pgtable-3level-defs.h |    2 
 linux-2.6.12.post/arch/i386/Kconfig                     |   13 ++
 linux-2.6.12.post/arch/i386/kernel/Makefile             |    1 
 linux-2.6.12.post/arch/i386/kernel/smpalts.c            |   85 ++++++++++++++++
 linux-2.6.12.post/arch/i386/kernel/smpboot.c            |    5 
 linux-2.6.12.post/arch/i386/kernel/vmlinux.lds.S        |    7 +
 linux-2.6.12.post/include/asm-i386/atomic.h             |    7 -
 linux-2.6.12.post/include/asm-i386/bitops.h             |   19 +--
 linux-2.6.12.post/include/asm-i386/rwsem.h              |   17 +--
 linux-2.6.12.post/include/asm-i386/smp_alt.h            |   32 ++++++
 linux-2.6.12.post/include/asm-i386/spinlock.h           |   41 ++++++-
 linux-2.6.12.post/include/asm-i386/system.h             |   58 +++++++++-
 20 files changed, 297 insertions(+), 53 deletions(-)

--- NEW FILE linux-2.6-xen-additional.patch ---
diff -urNpP linux-2.6.12/arch/i386/mm/init.c linux-2.6.12.new/arch/i386/mm/init.c
--- linux-2.6.12/arch/i386/mm/init.c	2005-06-17 20:48:29.000000000 +0100
+++ linux-2.6.12.new/arch/i386/mm/init.c	2005-07-11 16:28:09.778165582 +0100
@@ -634,7 +634,7 @@ void __init pgtable_cache_init(void)
 				PTRS_PER_PGD*sizeof(pgd_t),
 				0,
 				pgd_ctor,
-				PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
+				pgd_dtor);
 	if (!pgd_cache)
 		panic("pgtable_cache_init(): Cannot create pgd cache");
 }
diff -urNpP linux-2.6.12/arch/i386/mm/pageattr.c linux-2.6.12.new/arch/i386/mm/pageattr.c
--- linux-2.6.12/arch/i386/mm/pageattr.c	2005-06-17 20:48:29.000000000 +0100
+++ linux-2.6.12.new/arch/i386/mm/pageattr.c	2005-07-11 16:28:09.775165494 +0100
@@ -75,7 +75,7 @@ static void set_pmd_pte(pte_t *kpte, uns
 	unsigned long flags;
 
 	set_pte_atomic(kpte, pte); 	/* change init_mm */
-	if (PTRS_PER_PMD > 1)
+	if (HAVE_SHARED_KERNEL_PMD)
 		return;
 
 	spin_lock_irqsave(&pgd_lock, flags);
diff -urNpP linux-2.6.12/arch/i386/mm/pgtable.c linux-2.6.12.new/arch/i386/mm/pgtable.c
--- linux-2.6.12/arch/i386/mm/pgtable.c	2005-06-17 20:48:29.000000000 +0100
+++ linux-2.6.12.new/arch/i386/mm/pgtable.c	2005-07-11 16:32:01.478023726 +0100
@@ -199,14 +199,14 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
 {
 	unsigned long flags;
 
-	if (PTRS_PER_PMD == 1)
+	if (!HAVE_SHARED_KERNEL_PMD)
 		spin_lock_irqsave(&pgd_lock, flags);
 
 	memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
 			swapper_pg_dir + USER_PTRS_PER_PGD,
 			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
 
-	if (PTRS_PER_PMD > 1)
+	if (HAVE_SHARED_KERNEL_PMD)
 		return;
 
 	pgd_list_add(pgd);
@@ -214,11 +214,13 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
 	memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
 }
 
-/* never called when PTRS_PER_PMD > 1 */
 void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
 {
 	unsigned long flags; /* can be called from interrupt context */
 
+	if (HAVE_SHARED_KERNEL_PMD)
+		return;
+
 	spin_lock_irqsave(&pgd_lock, flags);
 	pgd_list_del(pgd);
 	spin_unlock_irqrestore(&pgd_lock, flags);
@@ -226,12 +228,29 @@ void pgd_dtor(void *pgd, kmem_cache_t *c
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	int i;
+	int i = 0;
 	pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
 
 	if (PTRS_PER_PMD == 1 || !pgd)
 		return pgd;
 
+	if (!HAVE_SHARED_KERNEL_PMD) {
+		/* alloc and copy kernel pmd */
+		unsigned long flags;
+		pgd_t *copy_pgd = pgd_offset_k(PAGE_OFFSET);
+		pud_t *copy_pud = pud_offset(copy_pgd, PAGE_OFFSET);
+		pmd_t *copy_pmd = pmd_offset(copy_pud, PAGE_OFFSET);
+		pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
+		if (0 == pmd)
+			goto out_oom;
+
+		spin_lock_irqsave(&pgd_lock, flags);
+		memcpy(pmd, copy_pmd, PAGE_SIZE);
+		spin_unlock_irqrestore(&pgd_lock, flags);
+		set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
+	}
+
+	/* alloc user pmds */
 	for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
 		pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
 		if (!pmd)
@@ -252,9 +271,16 @@ void pgd_free(pgd_t *pgd)
 	int i;
 
 	/* in the PAE case user pgd entries are overwritten before usage */
-	if (PTRS_PER_PMD > 1)
-		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
-			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+	if (PTRS_PER_PMD > 1) {
+		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
+			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
+			kmem_cache_free(pmd_cache, pmd);
+		}
+		if (!HAVE_SHARED_KERNEL_PMD) {
+			pmd_t *pmd = (void *)__va(pgd_val(pgd[USER_PTRS_PER_PGD])-1);
+			kmem_cache_free(pmd_cache, pmd);
+		}
+	}
 	/* in the non-PAE case, free_pgtables() clears user pgd entries */
 	kmem_cache_free(pgd_cache, pgd);
 }
diff -urNpP linux-2.6.12/include/asm-i386/pgtable-2level-defs.h linux-2.6.12.new/include/asm-i386/pgtable-2level-defs.h
--- linux-2.6.12/include/asm-i386/pgtable-2level-defs.h	2005-06-17 20:48:29.000000000 +0100
+++ linux-2.6.12.new/include/asm-i386/pgtable-2level-defs.h	2005-07-11 16:28:09.733164251 +0100
@@ -1,6 +1,8 @@
 #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
 #define _I386_PGTABLE_2LEVEL_DEFS_H
 
+#define HAVE_SHARED_KERNEL_PMD 0
+
 /*
  * traditional i386 two-level paging structure:
  */
diff -urNpP linux-2.6.12/include/asm-i386/pgtable-3level-defs.h linux-2.6.12.new/include/asm-i386/pgtable-3level-defs.h
--- linux-2.6.12/include/asm-i386/pgtable-3level-defs.h	2005-06-17 20:48:29.000000000 +0100
+++ linux-2.6.12.new/include/asm-i386/pgtable-3level-defs.h	2005-07-11 16:28:09.755164902 +0100
@@ -1,6 +1,8 @@
 #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
 #define _I386_PGTABLE_3LEVEL_DEFS_H
 
+#define HAVE_SHARED_KERNEL_PMD 1
+
 /*
  * PGDIR_SHIFT determines what a top-level page table entry can map
  */
diff -ur linux-2.6.11/kernel/rcupdate.c linux-2.6.11-rcu/kernel/rcupdate.c
--- linux-2.6.11/kernel/rcupdate.c	2005-05-30 10:51:41 +01:00
+++ linux-2.6.11-rcu/kernel/rcupdate.c	2005-05-30 10:53:53 +01:00
@@ -202,8 +202,11 @@
  */
 static void cpu_quiet(int cpu, struct rcu_ctrlblk *rcp, struct rcu_state *rsp)
 {
+	cpumask_t mask;
+
 	cpu_clear(cpu, rsp->cpumask);
-	if (cpus_empty(rsp->cpumask)) {
+	cpus_andnot(mask, rsp->cpumask, nohz_cpu_mask);
+	if (cpus_empty(mask)) {
 		/* batch completed ! */
 		rcp->completed = rcp->cur;
 		rcu_start_batch(rcp, rsp, 0);
diff -Naur linux-2.6.12/arch/i386/Kconfig linux-2.6.12.post/arch/i386/Kconfig
--- linux-2.6.12/arch/i386/Kconfig	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/arch/i386/Kconfig	2005-07-25 05:51:21.000000000 -0400
@@ -487,6 +487,19 @@
 
 	  If you don't know what to do here, say N.
 
+config SMP_ALTERNATIVES
+	bool "SMP alternatives support (EXPERIMENTAL)"
+	depends on SMP && EXPERIMENTAL
+	help
+	  Try to reduce the overhead of running an SMP kernel on a uniprocessor
+	  host slightly by replacing certain key instruction sequences
+	  according to whether we currently have more than one CPU available.
+	  This should provide a noticeable boost to performance when
+	  running SMP kernels on UP machines, and have negligible impact
+	  when running on an true SMP host.
+
+          If unsure, say N.
+	  
 config NR_CPUS
 	int "Maximum number of CPUs (2-255)"
 	range 2 255
diff -Naur linux-2.6.12/arch/i386/kernel/Makefile linux-2.6.12.post/arch/i386/kernel/Makefile
--- linux-2.6.12/arch/i386/kernel/Makefile	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/arch/i386/kernel/Makefile	2005-07-25 05:51:21.000000000 -0400
@@ -33,6 +33,7 @@
 obj-$(CONFIG_HPET_TIMER) 	+= time_hpet.o
 obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_SMP_ALTERNATIVES)  += smpalts.o
 
 EXTRA_AFLAGS   := -traditional
 
diff -Naur linux-2.6.12/arch/i386/kernel/smpalts.c linux-2.6.12.post/arch/i386/kernel/smpalts.c
--- linux-2.6.12/arch/i386/kernel/smpalts.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.12.post/arch/i386/kernel/smpalts.c	2005-07-25 05:51:21.000000000 -0400
@@ -0,0 +1,85 @@
+#include <linux/kernel.h>
+#include <asm/system.h>
+#include <asm/smp_alt.h>
+#include <asm/processor.h>
+#include <asm/string.h>
+
+struct smp_replacement_record {
+	unsigned char targ_size;
+	unsigned char smp1_size;
+	unsigned char smp2_size;
+	unsigned char up_size;
+	unsigned char feature;
+	unsigned char data[0];
+};
+
+struct smp_alternative_record {
+	void *targ_start;
+	struct smp_replacement_record *repl;
+};
+
+extern struct smp_alternative_record __start_smp_alternatives_table,
+  __stop_smp_alternatives_table;
+extern unsigned long __init_begin, __init_end;
+
+void prepare_for_smp(void)
+{
+	struct smp_alternative_record *r;
+	printk(KERN_INFO "Enabling SMP...\n");
+	for (r = &__start_smp_alternatives_table;
+	     r != &__stop_smp_alternatives_table;
+	     r++) {
+		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
+		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
+		BUG_ON(r->repl->targ_size < r->repl->up_size);
+               if (system_state == SYSTEM_RUNNING &&
+                   r->targ_start >= (void *)&__init_begin &&
+                   r->targ_start < (void *)&__init_end)
+                       continue;
+		if (r->repl->feature != (unsigned char)-1 &&
+		    boot_cpu_has(r->repl->feature)) {
+			memcpy(r->targ_start,
+			       r->repl->data + r->repl->smp1_size,
+			       r->repl->smp2_size);
+			memset(r->targ_start + r->repl->smp2_size,
+			       0x90,
+			       r->repl->targ_size - r->repl->smp2_size);
+		} else {
+			memcpy(r->targ_start,
+			       r->repl->data,
+			       r->repl->smp1_size);
+			memset(r->targ_start + r->repl->smp1_size,
+			       0x90,
+			       r->repl->targ_size - r->repl->smp1_size);
+		}
+	}
+	/* Paranoia */
+	asm volatile ("jmp 1f\n1:");
+	mb();
+}
+
+void unprepare_for_smp(void)
+{
+	struct smp_alternative_record *r;
+	printk(KERN_INFO "Disabling SMP...\n");
+	for (r = &__start_smp_alternatives_table;
+	     r != &__stop_smp_alternatives_table;
+	     r++) {
+		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
+		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
+		BUG_ON(r->repl->targ_size < r->repl->up_size);
+               if (system_state == SYSTEM_RUNNING &&
+                   r->targ_start >= (void *)&__init_begin &&
+                   r->targ_start < (void *)&__init_end)
+                       continue;
+		memcpy(r->targ_start,
+		       r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
+		       r->repl->up_size);
+		memset(r->targ_start + r->repl->up_size,
+		       0x90,
+		       r->repl->targ_size - r->repl->up_size);
+	}
+	/* Paranoia */
+	asm volatile ("jmp 1f\n1:");
+	mb();
+}
diff -Naur linux-2.6.12/arch/i386/kernel/smpboot.c linux-2.6.12.post/arch/i386/kernel/smpboot.c
--- linux-2.6.12/arch/i386/kernel/smpboot.c	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/arch/i386/kernel/smpboot.c	2005-07-25 05:51:21.000000000 -0400
@@ -1130,6 +1135,11 @@
 		return -EIO;
 	}
 
+#ifdef CONFIG_SMP_ALTERNATIVES
+	if (num_online_cpus() == 1)
+		prepare_for_smp();
+#endif
+
 	local_irq_enable();
 	/* Unleash the CPU! */
 	cpu_set(cpu, smp_commenced_mask);
diff -Naur linux-2.6.12/arch/i386/kernel/vmlinux.lds.S linux-2.6.12.post/arch/i386/kernel/vmlinux.lds.S
--- linux-2.6.12/arch/i386/kernel/vmlinux.lds.S	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/arch/i386/kernel/vmlinux.lds.S	2005-07-25 05:51:21.000000000 -0400
@@ -30,6 +30,13 @@
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
+  . = ALIGN(16);
+  __start_smp_alternatives_table = .;
+  __smp_alternatives : { *(__smp_alternatives) }
+  __stop_smp_alternatives_table = .;
+
+  __smp_replacements : { *(__smp_replacements) }
+
   RODATA
 
   /* writeable */
diff -Naur linux-2.6.12/include/asm-i386/atomic.h linux-2.6.12.post/include/asm-i386/atomic.h
--- linux-2.6.12/include/asm-i386/atomic.h	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/include/asm-i386/atomic.h	2005-07-25 05:51:21.000000000 -0400
@@ -4,18 +4,13 @@
 #include <linux/config.h>
 #include <linux/compiler.h>
 #include <asm/processor.h>
+#include <asm/smp_alt.h>
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
  * resource counting etc..
  */
 
-#ifdef CONFIG_SMP
-#define LOCK "lock ; "
-#else
-#define LOCK ""
-#endif
-
 /*
  * Make sure gcc doesn't try to be clever and move things around
  * on us. We need to use _exactly_ the address the user gave us,
diff -Naur linux-2.6.12/include/asm-i386/bitops.h linux-2.6.12.post/include/asm-i386/bitops.h
--- linux-2.6.12/include/asm-i386/bitops.h	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/include/asm-i386/bitops.h	2005-07-25 05:51:21.000000000 -0400
@@ -7,6 +7,7 @@
 
 #include <linux/config.h>
 #include <linux/compiler.h>
+#include <asm/smp_alt.h>
 
 /*
  * These have to be done with inline assembly: that way the bit-setting
@@ -16,12 +17,6 @@
  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  */
 
-#ifdef CONFIG_SMP
-#define LOCK_PREFIX "lock ; "
-#else
-#define LOCK_PREFIX ""
-#endif
-
 #define ADDR (*(volatile long *) addr)
 
 /**
@@ -41,7 +36,7 @@
  */
 static inline void set_bit(int nr, volatile unsigned long * addr)
 {
-	__asm__ __volatile__( LOCK_PREFIX
+	__asm__ __volatile__( LOCK
 		"btsl %1,%0"
 		:"=m" (ADDR)
 		:"Ir" (nr));
@@ -76,7 +71,7 @@
  */
 static inline void clear_bit(int nr, volatile unsigned long * addr)
 {
-	__asm__ __volatile__( LOCK_PREFIX
+	__asm__ __volatile__( LOCK
 		"btrl %1,%0"
 		:"=m" (ADDR)
 		:"Ir" (nr));
@@ -121,7 +116,7 @@
  */
 static inline void change_bit(int nr, volatile unsigned long * addr)
 {
-	__asm__ __volatile__( LOCK_PREFIX
+	__asm__ __volatile__( LOCK
 		"btcl %1,%0"
 		:"=m" (ADDR)
 		:"Ir" (nr));
@@ -140,7 +135,7 @@
 {
 	int oldbit;
 
-	__asm__ __volatile__( LOCK_PREFIX
+	__asm__ __volatile__( LOCK
 		"btsl %2,%1\n\tsbbl %0,%0"
 		:"=r" (oldbit),"=m" (ADDR)
 		:"Ir" (nr) : "memory");
@@ -180,7 +175,7 @@
 {
 	int oldbit;
 
-	__asm__ __volatile__( LOCK_PREFIX
+	__asm__ __volatile__( LOCK
 		"btrl %2,%1\n\tsbbl %0,%0"
 		:"=r" (oldbit),"=m" (ADDR)
 		:"Ir" (nr) : "memory");
@@ -231,7 +226,7 @@
 {
 	int oldbit;
 
-	__asm__ __volatile__( LOCK_PREFIX
+	__asm__ __volatile__( LOCK
 		"btcl %2,%1\n\tsbbl %0,%0"
 		:"=r" (oldbit),"=m" (ADDR)
 		:"Ir" (nr) : "memory");
diff -Naur linux-2.6.12/include/asm-i386/rwsem.h linux-2.6.12.post/include/asm-i386/rwsem.h
--- linux-2.6.12/include/asm-i386/rwsem.h	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/include/asm-i386/rwsem.h	2005-07-25 05:51:21.000000000 -0400
@@ -40,6 +40,7 @@
 
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <asm/smp_alt.h>
 
 struct rwsem_waiter;
 
@@ -99,7 +100,7 @@
 {
 	__asm__ __volatile__(
 		"# beginning down_read\n\t"
-LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
+LOCK	        "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
 		"  js        2f\n\t" /* jump if we weren't granted the lock */
 		"1:\n\t"
 		LOCK_SECTION_START("")
@@ -130,7 +131,7 @@
 		"  movl	     %1,%2\n\t"
 		"  addl      %3,%2\n\t"
 		"  jle	     2f\n\t"
-LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
+LOCK	        "  cmpxchgl  %2,%0\n\t"
 		"  jnz	     1b\n\t"
 		"2:\n\t"
 		"# ending __down_read_trylock\n\t"
@@ -150,7 +151,7 @@
 	tmp = RWSEM_ACTIVE_WRITE_BIAS;
 	__asm__ __volatile__(
 		"# beginning down_write\n\t"
-LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
+LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
 		"  testl     %%edx,%%edx\n\t" /* was the count 0 before? */
 		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
 		"1:\n\t"
@@ -188,7 +189,7 @@
 	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
 	__asm__ __volatile__(
 		"# beginning __up_read\n\t"
-LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
+LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
 		LOCK_SECTION_START("")
@@ -214,7 +215,7 @@
 	__asm__ __volatile__(
 		"# beginning __up_write\n\t"
 		"  movl      %2,%%edx\n\t"
-LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
+LOCK	        "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
 		LOCK_SECTION_START("")
@@ -239,7 +240,7 @@
 {
 	__asm__ __volatile__(
 		"# beginning __downgrade_write\n\t"
-LOCK_PREFIX	"  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
+LOCK	        "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
 		LOCK_SECTION_START("")
@@ -263,7 +264,7 @@
 static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
 {
 	__asm__ __volatile__(
-LOCK_PREFIX	"addl %1,%0"
+LOCK	          "addl %1,%0"
 		: "=m"(sem->count)
 		: "ir"(delta), "m"(sem->count));
 }
@@ -276,7 +277,7 @@
 	int tmp = delta;
 
 	__asm__ __volatile__(
-LOCK_PREFIX	"xadd %0,(%2)"
+LOCK  	          "xadd %0,(%2)"
 		: "+r"(tmp), "=m"(sem->count)
 		: "r"(sem), "m"(sem->count)
 		: "memory");
diff -Naur linux-2.6.12/include/asm-i386/smp_alt.h linux-2.6.12.post/include/asm-i386/smp_alt.h
--- linux-2.6.12/include/asm-i386/smp_alt.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.12.post/include/asm-i386/smp_alt.h	2005-07-25 05:51:21.000000000 -0400
@@ -0,0 +1,32 @@
+#ifndef __ASM_SMP_ALT_H__
+#define __ASM_SMP_ALT_H__
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
+#define LOCK \
+        "6677: nop\n" \
+	".section __smp_alternatives,\"a\"\n" \
+	".long 6677b\n" \
+	".long 6678f\n" \
+	".previous\n" \
+	".section __smp_replacements,\"a\"\n" \
+	"6678: .byte 1\n" \
+	".byte 1\n" \
+	".byte 0\n" \
+        ".byte 1\n" \
+	".byte -1\n" \
+	"lock\n" \
+	"nop\n" \
+	".previous\n"
+void prepare_for_smp(void);
+void unprepare_for_smp(void);
+#else
+#define LOCK "lock ; "
+#endif
+#else
+#define LOCK ""
+#endif
+
+#endif /* __ASM_SMP_ALT_H__ */
diff -Naur linux-2.6.12/include/asm-i386/spinlock.h linux-2.6.12.post/include/asm-i386/spinlock.h
--- linux-2.6.12/include/asm-i386/spinlock.h	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/include/asm-i386/spinlock.h	2005-07-25 05:51:21.000000000 -0400
@@ -6,6 +6,7 @@
 #include <asm/page.h>
 #include <linux/config.h>
 #include <linux/compiler.h>
+#include <asm/smp_alt.h>
 
 asmlinkage int printk(const char * fmt, ...)
 	__attribute__ ((format (printf, 1, 2)));
@@ -47,8 +48,9 @@
 #define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
 
 #define spin_lock_string \
-	"\n1:\t" \
-	"lock ; decb %0\n\t" \
+        "1:\n" \
+	LOCK \
+	"decb %0\n\t" \
 	"jns 3f\n" \
 	"2:\t" \
 	"rep;nop\n\t" \
@@ -58,8 +60,9 @@
 	"3:\n\t"
 
 #define spin_lock_string_flags \
-	"\n1:\t" \
-	"lock ; decb %0\n\t" \
+        "1:\n" \
+	LOCK \
+	"decb %0\n\t" \
 	"jns 4f\n\t" \
 	"2:\t" \
 	"testl $0x200, %1\n\t" \
@@ -121,10 +124,34 @@
 static inline int _raw_spin_trylock(spinlock_t *lock)
 {
 	char oldval;
+#ifdef CONFIG_SMP_ALTERNATIVES
 	__asm__ __volatile__(
-		"xchgb %b0,%1"
+		"1:movb %1,%b0\n"
+		"movb $0,%1\n"
+		"2:"
+		".section __smp_alternatives,\"a\"\n"
+		".long 1b\n"
+		".long 3f\n"
+		".previous\n"
+		".section __smp_replacements,\"a\"\n"
+		"3: .byte 2b - 1b\n"
+		".byte 5f-4f\n"
+		".byte 0\n"
+		".byte 6f-5f\n"
+		".byte -1\n"
+		"4: xchgb %b0,%1\n"
+		"5: movb %1,%b0\n"
+		"movb $0,%1\n"
+		"6:\n"
+		".previous\n"
 		:"=q" (oldval), "=m" (lock->slock)
 		:"0" (0) : "memory");
+#else
+	__asm__ __volatile__(
+		"xchgb %b0,%1\n"
+		:"=q" (oldval), "=m" (lock->slock)
+		:"0" (0) : "memory");
+#endif
 	return oldval > 0;
 }
 
@@ -225,8 +252,8 @@
 	__build_write_lock(rw, "__write_lock_failed");
 }
 
-#define _raw_read_unlock(rw)		asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
-#define _raw_write_unlock(rw)	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
+#define _raw_read_unlock(rw)	asm volatile(LOCK "incl %0" :"=m" ((rw)->lock) : : "memory")
+#define _raw_write_unlock(rw)	asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
 
 static inline int _raw_read_trylock(rwlock_t *lock)
 {
diff -Naur linux-2.6.12/include/asm-i386/system.h linux-2.6.12.post/include/asm-i386/system.h
--- linux-2.6.12/include/asm-i386/system.h	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12.post/include/asm-i386/system.h	2005-07-25 05:51:21.000000000 -0400
@@ -5,7 +5,7 @@
 #include <linux/kernel.h>
 #include <asm/segment.h>
 #include <asm/cpufeature.h>
-#include <linux/bitops.h> /* for LOCK_PREFIX */
+#include <asm/smp_alt.h>
 
 #ifdef __KERNEL__
 
@@ -249,19 +249,19 @@
 	unsigned long prev;
 	switch (size) {
 	case 1:
-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+		__asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
 				     : "=a"(prev)
 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
 				     : "memory");
 		return prev;
 	case 2:
-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+		__asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
 				     : "=a"(prev)
 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
 				     : "memory");
 		return prev;
 	case 4:
-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
+		__asm__ __volatile__(LOCK "cmpxchgl %1,%2"
 				     : "=a"(prev)
 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
 				     : "memory");
@@ -425,11 +425,55 @@
 #endif
 
 #ifdef CONFIG_SMP
-#define smp_mb()	mb()
-#define smp_rmb()	rmb()
 #define smp_wmb()	wmb()
-#define smp_read_barrier_depends()	read_barrier_depends()
+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
+#define smp_alt_mb(instr)                                           \
+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
+		     ".section __smp_alternatives,\"a\"\n"          \
+		     ".long 6667b\n"                                \
+                     ".long 6673f\n"                                \
+		     ".previous\n"                                  \
+		     ".section __smp_replacements,\"a\"\n"          \
+		     "6673:.byte 6668b-6667b\n"                     \
+		     ".byte 6670f-6669f\n"                          \
+		     ".byte 6671f-6670f\n"                          \
+                     ".byte 0\n"                                    \
+		     ".byte %c0\n"                                  \
+		     "6669:lock;addl $0,0(%%esp)\n"                 \
+		     "6670:" instr "\n"                             \
+		     "6671:\n"                                      \
+		     ".previous\n"                                  \
+		     :                                              \
+		     : "i" (X86_FEATURE_XMM2)                       \
+		     : "memory")
+#define smp_rmb() smp_alt_mb("lfence")
+#define smp_mb()  smp_alt_mb("mfence")
+#define set_mb(var, value) do {                                     \
+unsigned long __set_mb_temp;                                        \
+__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
+		     ".section __smp_alternatives,\"a\"\n"          \
+		     ".long 6667b\n"                                \
+		     ".long 6673f\n"                                \
+		     ".previous\n"                                  \
+		     ".section __smp_replacements,\"a\"\n"          \
+		     "6673: .byte 6668b-6667b\n"                    \
+		     ".byte 6670f-6669f\n"                          \
+		     ".byte 0\n"                                    \
+		     ".byte 6671f-6670f\n"                          \
+		     ".byte -1\n"                                   \
+		     "6669: xchg %1, %0\n"                          \
+		     "6670:movl %1, %0\n"                           \
+		     "6671:\n"                                      \
+		     ".previous\n"                                  \
+		     : "=m" (var), "=r" (__set_mb_temp)             \
+		     : "1" (value)                                  \
+		     : "memory"); } while (0)
+#else
+#define smp_rmb()	rmb()
+#define smp_mb()	mb()
 #define set_mb(var, value) do { xchg(&var, value); } while (0)
+#endif
+#define smp_read_barrier_depends()	read_barrier_depends()
 #else
 #define smp_mb()	barrier()
 #define smp_rmb()	barrier()
diff -urN linux-2.6.10-orig/include/asm-x86_64/hw_irq.h linux-2.6.10/include/asm-x86_64/hw_irq.h
--- linux-2.6.10-orig/include/asm-x86_64/hw_irq.h	2005-01-06 00:34:38.000000000 -0500
+++ linux-2.6.10/include/asm-x86_64/hw_irq.h	2005-02-25 17:45:37.181518088 -0500
@@ -48,6 +48,7 @@
  *
  *  Vectors 0xf0-0xf9 are free (reserved for future Linux use).
  */
+#ifndef CONFIG_XEN
 #define SPURIOUS_APIC_VECTOR	0xff
 #define ERROR_APIC_VECTOR	0xfe
 #define INVALIDATE_TLB_VECTOR	0xfd
@@ -57,7 +58,7 @@
 #define KDB_VECTOR	0xf9
 
 #define THERMAL_APIC_VECTOR	0xf0
-
+#endif
 
 /*
  * Local APIC timer IRQ vector is on a different priority level,
diff -urN linux-2.6.10-orig/include/asm-x86_64/irq.h linux-2.6.10/include/asm-x86_64/irq.h
--- linux-2.6.10-orig/include/asm-x86_64/irq.h	2005-01-06 00:34:38.000000000 -0500
+++ linux-2.6.10/include/asm-x86_64/irq.h	2005-02-25 17:45:37.181518088 -0500
@@ -10,6 +10,9 @@
  *	<tomsoft at informatik.tu-chemnitz.de>
  */
 
+#ifdef CONFIG_XEN
+#include "irq_vectors.h"
+#endif
 #define TIMER_IRQ 0
 
 /*
@@ -22,6 +25,7 @@
  * the usable vector space is 0x20-0xff (224 vectors)
  */
 
+#ifndef CONFIG_XEN
 /*
  * The maximum number of vectors supported by x86_64 processors
  * is limited to 256. For processors other than x86_64, NR_VECTORS
@@ -38,6 +42,7 @@
 #define NR_IRQS 224
 #define NR_IRQ_VECTORS 1024
 #endif
+#endif
 
 static __inline__ int irq_canonicalize(int irq)
 {
diff -urN linux-2.6.10-orig/include/asm-x86_64/posix_types.h linux-2.6.10/include/asm-x86_64/posix_types.h
--- linux-2.6.10-orig/include/asm-x86_64/posix_types.h	2004-10-18 17:55:29.000000000 -0400
+++ linux-2.6.10/include/asm-x86_64/posix_types.h	2005-02-25 17:45:37.183517784 -0500
@@ -6,7 +6,7 @@
  * be a little careful about namespace pollution etc.  Also, we cannot
  * assume GCC is being used.
  */
-
+#ifndef __ASSEMBLY__
 typedef unsigned long	__kernel_ino_t;
 typedef unsigned int	__kernel_mode_t;
 typedef unsigned long	__kernel_nlink_t;
@@ -115,5 +115,5 @@
 }
 
 #endif /* defined(__KERNEL__) */
-
+#endif
 #endif

linux-2.6-xen-compile.patch:
 linux-2.6.10/arch/xen/i386/pci/irq.c                |    1 +
 linux-2.6.12/arch/i386/kernel/vmlinux.lds.S         |    4 ++--
 linux-2.6.12/arch/xen/Kconfig                       |    1 +
 linux-2.6.12/arch/xen/Kconfig.drivers               |    2 +-
 linux-2.6.12/arch/xen/i386/Kconfig                  |   11 +++++++++++
 linux-2.6.12/arch/xen/i386/kernel/i386_ksyms.c      |    8 +-------
 linux-2.6.12/arch/xen/i386/kernel/process.c         |    4 ++--
 linux-2.6.12/arch/xen/i386/kernel/setup.c           |    8 ++++++++
 linux-2.6.12/arch/xen/i386/kernel/signal.c          |    2 +-
 linux-2.6.12/arch/xen/i386/kernel/time.c            |    6 +-----
 linux-2.6.12/arch/xen/i386/kernel/traps.c           |    4 ++--
 linux-2.6.12/arch/xen/i386/mm/pgtable.c             |    2 +-
 linux-2.6.12/arch/xen/i386/pci/irq.c                |   17 +++++++++++------
 linux-2.6.12/arch/xen/kernel/reboot.c               |    6 ++++++
 linux-2.6.12/drivers/char/tty_io.c                  |   19 ++++++++++++-------
 linux-2.6.12/include/asm-i386/timex.h               |    2 ++
 linux-2.6.12/include/asm-xen/asm-i386/mmu_context.h |    4 +---
 linux-2.6.12/include/asm-xen/asm-i386/page.h        |    3 +++
 linux-2.6.12/include/asm-xen/asm-i386/pci.h         |    2 +-
 linux-2.6.12/include/asm-xen/asm-i386/ptrace.h      |    4 ++++
 linux-2.6.12/include/linux/skbuff.h                 |    6 ++++--
 linux-2.6.12/net/core/dev.c                         |    4 ++++
 linux-2.6.8/arch/xen/i386/kernel/time.c             |    2 +-
 linux-2.6.9/Makefile                                |    2 +-
 linux-2.6.9/arch/xen/Makefile                       |    3 +++
 linux-2.6.9/arch/xen/boot/Makefile                  |    3 +++
 linux-2.6.9/kernel/profile.c                        |    1 +
 27 files changed, 89 insertions(+), 42 deletions(-)

--- NEW FILE linux-2.6-xen-compile.patch ---
#
# Chunks that gave rejects in the upstream generated Xen patch.
#
--- linux-2.6.12/drivers/char/tty_io.c.fixup	2005-08-23 13:02:02.000000000 -0400
+++ linux-2.6.12/drivers/char/tty_io.c	2005-08-23 13:04:24.000000000 -0400
@@ -2979,14 +2979,19 @@
 #endif
 
 #ifdef CONFIG_VT
-	cdev_init(&vc0_cdev, &console_fops);
-	if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
-	    register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
-		panic("Couldn't register /dev/tty0 driver\n");
-	devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
-	class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
+	if (console_use_vt) {
+		cdev_init(&vc0_cdev, &console_fops);
+		if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
+		    register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1,
+						"/dev/vc/0") < 0)
+			panic("Couldn't register /dev/tty0 driver\n");
+		devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR,
+				 "vc/0");
+		class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL,
+				 "tty0");
 
-	vty_init();
+		vty_init();
+	}
 #endif
 	return 0;
 }
--- linux-2.6.12/include/linux/skbuff.h.fixup	2005-08-23 13:02:10.000000000 -0400
+++ linux-2.6.12/include/linux/skbuff.h	2005-08-23 13:05:28.000000000 -0400
@@ -254,8 +254,10 @@
 	__u8			local_df:1,
 				cloned:1,
 				ip_summed:2,
-				nohdr:1;
-				/* 3 bits spare */
+				nohdr:1,
+				proto_csum_valid:1,
+				proto_csum_blank:1;
+				/* 1 bit spare */
 	__u8			pkt_type;
 	__be16			protocol;
 
--- linux-2.6.12/net/core/dev.c.fixup	2005-08-23 13:02:21.000000000 -0400
+++ linux-2.6.12/net/core/dev.c	2005-08-23 13:06:08.000000000 -0400
@@ -115,6 +115,10 @@
 #endif	/* CONFIG_NET_RADIO */
 #include <asm/current.h>
 
+#include <net/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+
 /*
  *	The list of packet types we will receive (as opposed to discard)
  *	and the routines to invoke.

#
# Other compile fixes
#
--- linux-2.6.8/arch/xen/i386/kernel/time.c.269	2004-10-15 13:40:26.000000000 -0400
+++ linux-2.6.8/arch/xen/i386/kernel/time.c	2004-10-15 13:40:40.000000000 -0400
@@ -68,7 +68,7 @@
 
 #include "io_ports.h"
 
-extern spinlock_t i8259A_lock;
+spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
 int pit_latch_buggy;              /* extern */
 
 #include "do_timer.h"
--- linux-2.6.9/kernel/profile.c~	2004-12-24 01:45:26.735454624 -0500
+++ linux-2.6.9/kernel/profile.c	2004-12-24 01:45:40.875305040 -0500
@@ -22,6 +22,7 @@
 #include <linux/cpumask.h>
 #include <linux/cpu.h>
 #include <linux/profile.h>
+#include <linux/ptrace.h>
 #include <linux/highmem.h>
 #include <asm/sections.h>
 #include <asm/semaphore.h>
--- linux-2.6.9/arch/xen/boot/Makefile.bzi	2004-11-17 22:07:46.000000000 -0500
+++ linux-2.6.9/arch/xen/boot/Makefile	2004-11-17 22:12:07.000000000 -0500
@@ -6,3 +6,6 @@ vmlinuz: vmlinux-stripped FORCE
 
 vmlinux-stripped: vmlinux FORCE
 	$(call if_changed,objcopy)
+
+bzImage: vmlinuz
+	ln -sf ../../../vmlinuz $(srctree)/arch/xen/boot/bzImage
unchanged:
--- linux-2.6.9/arch/xen/Makefile.bzi	2004-11-17 22:07:34.000000000 -0500
+++ linux-2.6.9/arch/xen/Makefile	2004-11-17 22:07:40.000000000 -0500
@@ -45,6 +45,9 @@ all: vmlinuz
 vmlinuz: vmlinux
 	$(Q)$(MAKE) $(build)=arch/xen/boot vmlinuz
 
+bzImage: vmlinuz
+	$(Q)$(MAKE) $(build)=arch/xen/boot bzImage
+
 XINSTALL_NAME ?= $(KERNELRELEASE)
 install: vmlinuz
 	mkdir -p $(INSTALL_PATH)/boot
--- linux-2.6.9/Makefile.xenness	2004-11-18 11:53:26.000000000 -0500
+++ linux-2.6.9/Makefile	2004-11-18 11:53:54.000000000 -0500
@@ -921,7 +921,7 @@ CLEAN_FILES +=	vmlinux System.map \
 MRPROPER_DIRS  += include/config include2
 MRPROPER_FILES += .config .config.old include/asm .version \
                   include/linux/autoconf.h include/linux/version.h \
-                  Module.symvers tags TAGS cscope*
+                  Module.symvers tags TAGS cscope* include/.asm-ignore
 
 # clean - Delete most, but leave enough to build external modules
 #
--- linux-2.6.10/arch/xen/i386/pci/irq.c.bk14	2005-01-11 17:45:55.000000000 -0500
+++ linux-2.6.10/arch/xen/i386/pci/irq.c	2005-01-11 17:47:04.000000000 -0500
@@ -37,6 +37,7 @@
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
 
+static int pirq_enable_irq(struct pci_dev *);
 
 static int __init pcibios_irq_init(void)
 {
--- linux-2.6.12/arch/xen/i386/kernel/process.c.compile	2005-08-23 10:42:33.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/process.c	2005-08-23 10:42:51.000000000 -0400
@@ -196,12 +196,12 @@
 
 			if (cpu_is_offline(cpu)) {
 				local_irq_disable();
+#if defined(CONFIG_XEN) && defined(CONFIG_HOTPLUG_CPU)
 				/* Ack it.  From this point on until
 				   we get woken up, we're not allowed
 				   to take any locks.  In particular,
 				   don't printk. */
 				__get_cpu_var(cpu_state) = CPU_DEAD;
-#if defined(CONFIG_XEN) && defined(CONFIG_HOTPLUG_CPU)
 				/* Tell hypervisor to take vcpu down. */
 				HYPERVISOR_vcpu_down(cpu);
 #endif
--- linux-2.6.12/arch/xen/i386/pci/irq.c.acpi	2005-08-15 11:03:50.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/pci/irq.c	2005-08-15 11:07:05.000000000 -0400
@@ -56,6 +56,7 @@ struct irq_router_handler {
 };
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
+void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
 
 /*
  *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
@@ -1010,24 +1011,28 @@ static int __init pcibios_irq_init(void)
 subsys_initcall(pcibios_irq_init);
 
 
-static void pirq_penalize_isa_irq(int irq)
+static void pirq_penalize_isa_irq(int irq, int active)
 {
 	/*
 	 *  If any ISAPnP device reports an IRQ in its list of possible
 	 *  IRQ's, we try to avoid assigning it to PCI devices.
 	 */
-	if (irq < 16)
-		pirq_penalty[irq] += 100;
+	if (irq < 16) {
+		if (active)
+			pirq_penalty[irq] += 1000;
+		else
+			pirq_penalty[irq] += 100;
+	}
 }
 
-void pcibios_penalize_isa_irq(int irq)
+void pcibios_penalize_isa_irq(int irq, int active)
 {
 #ifdef CONFIG_ACPI_PCI
 	if (!acpi_noirq)
-		acpi_penalize_isa_irq(irq);
+		acpi_penalize_isa_irq(irq, active);
 	else
 #endif
-		pirq_penalize_isa_irq(irq);
+		pirq_penalize_isa_irq(irq, active);
 }
 
 static int pirq_enable_irq(struct pci_dev *dev)
--- linux-2.6.12/include/asm-xen/asm-i386/pci.h.acpi	2005-08-15 11:07:41.000000000 -0400
+++ linux-2.6.12/include/asm-xen/asm-i386/pci.h	2005-08-15 11:08:33.000000000 -0400
@@ -27,7 +27,7 @@ void pcibios_config_init(void);
 struct pci_bus * pcibios_scan_root(int bus);
 
 void pcibios_set_master(struct pci_dev *dev);
-void pcibios_penalize_isa_irq(int irq);
+void pcibios_penalize_isa_irq(int irq, int active);
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 

#
# Linux 2.6.13 related compile fixes
#
--- linux-2.6.12/arch/xen/i386/kernel/signal.c.2613	2005-08-23 13:16:40.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/signal.c	2005-08-23 13:16:45.000000000 -0400
@@ -603,7 +603,7 @@
 		return 1;
 
 	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+		refrigerator();
 		goto no_signal;
 	}
 
--- linux-2.6.12/arch/xen/i386/kernel/traps.c.2613	2005-08-23 13:17:09.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/traps.c	2005-08-23 13:21:54.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/ptrace.h>
 #include <linux/utsname.h>
 #include <linux/kprobes.h>
+#include <linux/smp.h>
 
 #ifdef CONFIG_EISA
 #include <linux/ioport.h>
@@ -47,7 +48,6 @@
 #include <asm/i387.h>
 #include <asm/nmi.h>
 
-#include <asm/smp.h>
 #include <asm/arch_hooks.h>
 #include <asm/kdebug.h>
 
@@ -303,7 +303,7 @@
 	};
 	static int die_counter;
 
-	if (die.lock_owner != _smp_processor_id()) {
+	if (die.lock_owner != smp_processor_id()) {
 		console_verbose();
 		spin_lock_irq(&die.lock);
 		die.lock_owner = smp_processor_id();
--- linux-2.6.12/arch/xen/i386/kernel/time.c.2613	2005-08-23 13:18:17.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/time.c	2005-08-23 13:22:32.000000000 -0400
@@ -88,11 +88,7 @@
 struct timezone __sys_tz __section_sys_tz;
 #endif
 
-#if defined(__x86_64__)
 unsigned int cpu_khz;	/* Detected as we calibrate the TSC */
-#else
-unsigned long cpu_khz;	/* Detected as we calibrate the TSC */
-#endif
 
 extern unsigned long wall_jiffies;
 
@@ -772,7 +768,7 @@
 	update_wallclock();
 
 	init_cpu_khz();
-	printk(KERN_INFO "Xen reported: %lu.%03lu MHz processor.\n",
+	printk(KERN_INFO "Xen reported: %u.%03u MHz processor.\n",
 	       cpu_khz / 1000, cpu_khz % 1000);
 
 #if defined(__x86_64__)
--- linux-2.6.12/arch/xen/i386/kernel/i386_ksyms.c.2613	2005-08-23 13:22:50.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/i386_ksyms.c	2005-08-23 14:30:44.000000000 -0400
@@ -56,7 +56,7 @@
 EXPORT_SYMBOL(drive_info);
 #endif
 
-extern unsigned long cpu_khz;
+extern unsigned int cpu_khz;
 extern unsigned long get_cmos_time(void);
 
 /* platform dependent support */
@@ -69,7 +69,6 @@
 EXPORT_SYMBOL(xquad_portio);
 #endif
 EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL_GPL(kernel_fpu_begin);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(ioremap_nocache);
@@ -119,11 +118,6 @@
 EXPORT_SYMBOL(pci_mem_start);
 #endif
 
-#ifdef CONFIG_PCI_BIOS
-EXPORT_SYMBOL(pcibios_set_irq_routing);
-EXPORT_SYMBOL(pcibios_get_irq_routing_table);
-#endif
-
 #ifdef CONFIG_X86_USE_3DNOW
 EXPORT_SYMBOL(_mmx_memcpy);
 EXPORT_SYMBOL(mmx_clear_page);
--- linux-2.6.12/arch/xen/i386/mm/pgtable.c.2613	2005-08-23 13:26:16.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/mm/pgtable.c	2005-08-23 13:27:39.000000000 -0400
@@ -41,7 +41,7 @@
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; ++i) {
-			page = pgdat->node_mem_map + i;
+			page = pgdat_page_nr(pgdat, i);
 			total++;
 			if (PageHighMem(page))
 				highmem++;
--- linux-2.6.12/include/asm-xen/asm-i386/mmu_context.h.2613	2005-08-23 13:37:24.000000000 -0400
+++ linux-2.6.12/include/asm-xen/asm-i386/mmu_context.h	2005-08-23 14:25:43.000000000 -0400
@@ -23,9 +23,7 @@
 #endif
 }
 
-#define prepare_arch_switch(rq,next)	__prepare_arch_switch()
-#define finish_arch_switch(rq, next)	spin_unlock_irq(&(rq)->lock)
-#define task_running(rq, p)		((rq)->curr == (p))
+#define prepare_arch_switch(next)	__prepare_arch_switch()
 
 static inline void __prepare_arch_switch(void)
 {
--- linux-2.6.12/arch/i386/kernel/vmlinux.lds.S.2613	2005-08-23 19:42:43.000000000 -0400
+++ linux-2.6.12/arch/i386/kernel/vmlinux.lds.S	2005-08-23 19:43:25.000000000 -0400
@@ -35,10 +35,10 @@
 
   . = ALIGN(16);
   __start_smp_alternatives_table = .;
-  __smp_alternatives : { *(__smp_alternatives) }
+  __smp_alternatives : AT(ADDR(__smp_alternatives) - LOAD_OFFSET) { *(__smp_alternatives) }
   __stop_smp_alternatives_table = .;
 
-  __smp_replacements : { *(__smp_replacements) }
+  __smp_replacements : AT(ADDR(__smp_replacements) - LOAD_OFFSET) { *(__smp_replacements) }
 
   RODATA
 
--- linux-2.6.12/arch/xen/i386/Kconfig.2613	2005-08-23 20:19:47.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/Kconfig	2005-08-23 20:21:29.000000000 -0400
@@ -940,6 +940,17 @@
 	depends on X86 && !EMBEDDED
 	default y
 
+config PHYSICAL_START
+	hex "Physical address where the kernel is loaded" if EMBEDDED
+	default "0x100000"
+	help
+	  This gives the physical address where the kernel is loaded.
+	  Primarily used in the case of kexec on panic where the
+	  fail safe kernel needs to run at a different address than
+	  the panic-ed kernel.
+
+	  Don't change this unless you know what you are doing.
+
 config SECCOMP
 	bool "Enable seccomp to safely compute untrusted bytecode"
 	depends on PROC_FS
--- linux-2.6.12/include/asm-xen/asm-i386/page.h.2613	2005-08-23 20:16:08.000000000 -0400
+++ linux-2.6.12/include/asm-xen/asm-i386/page.h	2005-08-23 20:18:05.000000000 -0400
@@ -216,9 +216,12 @@
 
 #ifdef __ASSEMBLY__
 #define __PAGE_OFFSET		(0xC0000000)
+#define __PHYSICAL_START	CONFIG_PHYSICAL_START
 #else
 #define __PAGE_OFFSET		(0xC0000000UL)
+#define __PHYSICAL_START	((unsigned long)CONFIG_PHYSICAL_START)
 #endif
+#define __KERNEL_START		(__PAGE_OFFSET + __PHYSICAL_START)
 
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
--- linux-2.6.12/arch/xen/i386/kernel/process.c.2613	2005-08-23 20:32:31.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/process.c	2005-08-23 20:32:48.000000000 -0400
@@ -184,7 +184,7 @@
  */
 void cpu_idle (void)
 {
-	int cpu = _smp_processor_id();
+	int cpu = smp_processor_id();
 
 	/* endless idle loop with no priority at all */
 	while (1) {
--- linux-2.6.12/arch/xen/i386/kernel/setup.c.2613	2005-08-23 20:35:09.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/setup.c	2005-08-23 20:36:23.000000000 -0400
@@ -58,6 +58,14 @@
 #include "setup_arch_pre.h"
 #include <bios_ebda.h>
 
+#ifdef CONFIG_HOTPLUG_CPU
+#define DEFAULT_SEND_IPI	(1)
+#else
+#define DEFAULT_SEND_IPI	(0)
+#endif
+
+int no_broadcast=DEFAULT_SEND_IPI;
+
 /* Allows setting of maximum possible memory size  */
 static unsigned long xen_override_max_pfn;
 
--- linux-2.6.12/arch/xen/kernel/reboot.c.2613	2005-08-23 20:41:22.000000000 -0400
+++ linux-2.6.12/arch/xen/kernel/reboot.c	2005-08-23 20:42:16.000000000 -0400
@@ -32,6 +32,12 @@
 	HYPERVISOR_reboot();
 }
 
+void machine_emergency_restart(void)
+{
+	char dummy;
+	machine_restart(&dummy);
+}
+
 void machine_halt(void)
 {
 	machine_power_off();
--- linux-2.6.12/include/asm-i386/timex.h.2613	2005-08-23 20:31:58.000000000 -0400
+++ linux-2.6.12/include/asm-i386/timex.h	2005-08-23 20:32:15.000000000 -0400
@@ -49,7 +49,9 @@
 
 extern unsigned int cpu_khz;
 
+#ifndef CONFIG_XEN
 extern int read_current_timer(unsigned long *timer_value);
 #define ARCH_HAS_READ_CURRENT_TIMER	1
+#endif
 
 #endif
--- linux-2.6.12/include/asm-xen/asm-i386/ptrace.h.2613	2005-08-23 20:37:02.000000000 -0400
+++ linux-2.6.12/include/asm-xen/asm-i386/ptrace.h	2005-08-23 20:38:09.000000000 -0400
@@ -55,9 +55,13 @@
 #define PTRACE_SET_THREAD_AREA    26
 
 #ifdef __KERNEL__
+
+#include <asm/vm86.h>
+
 struct task_struct;
 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
 #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (2 & (regs)->xcs))
+#define user_mode_vm(regs) (((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0)
 #define instruction_pointer(regs) ((regs)->eip)
 #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
 extern unsigned long profile_pc(struct pt_regs *regs);
--- linux-2.6.12/arch/xen/Kconfig.drivers~	2005-08-27 00:23:32.000000000 -0400
+++ linux-2.6.12/arch/xen/Kconfig.drivers	2005-08-27 00:23:49.000000000 -0400
@@ -30,7 +30,7 @@ source "drivers/ieee1394/Kconfig"
 source "drivers/message/i2o/Kconfig"
 endif
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 if XEN_PHYSDEV_ACCESS
 source "drivers/isdn/Kconfig"
--- linux-2.6.12/arch/xen/Kconfig~	2005-08-27 00:23:54.000000000 -0400
+++ linux-2.6.12/arch/xen/Kconfig	2005-08-27 00:24:08.000000000 -0400
@@ -184,6 +184,7 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
 source "arch/xen/Kconfig.drivers"
 
 if XEN_PRIVILEGED_GUEST

linux-2.6-xen-kprobes.patch:
 Makefile |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6-xen-kprobes.patch ---
Merge kprobes for xen
---

 arch/i386/xen/kernel/Makefile |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/i386/xen/kernel/Makefile b/arch/i386/xen/kernel/Makefile
index b38389d..20c0129 100644
--- a/arch/i386/xen/kernel/Makefile
+++ b/arch/i386/xen/kernel/Makefile
@@ -35,6 +35,7 @@ c-obj-$(CONFIG_X86_REBOOTFIXUPS)	+= rebo
 c-obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
 c-obj-$(CONFIG_X86_NUMAQ)	+= numaq.o
 c-obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.o
+c-obj-$(CONFIG_KPROBES)		+= kprobes.o
 c-obj-$(CONFIG_MODULES)		+= module.o
 c-obj-y				+= sysenter.o
 obj-y				+= vsyscall.o

linux-2.6-xen-merge.patch:
 arch/i386/Kconfig                                   |   54 
 arch/i386/Makefile                                  |   38 
 arch/i386/kernel/Makefile                           |    1 
 arch/i386/kernel/smpalts.c                          |   85 
 arch/i386/kernel/smpboot.c                          |   10 
 arch/i386/kernel/vmlinux.lds.S                      |    7 
 arch/i386/mach-xen/Makefile                         |   13 
 arch/i386/mach-xen/setup.c                          |   37 
 arch/i386/xen/boot/Makefile                         |   21 
 arch/i386/xen/kernel/Makefile                       |   99 
 arch/i386/xen/kernel/acpi/Makefile                  |   17 
 arch/i386/xen/kernel/acpi/boot.c                    | 1157 ++++++++
 arch/i386/xen/kernel/apic.c                         |   89 
 arch/i386/xen/kernel/cpu/Makefile                   |   31 
 arch/i386/xen/kernel/cpu/common.c                   |  655 ++++
 arch/i386/xen/kernel/cpu/mtrr/Makefile              |   16 
 arch/i386/xen/kernel/cpu/mtrr/main.c                |  180 +
 arch/i386/xen/kernel/early_printk.c                 |    1 
 arch/i386/xen/kernel/entry.S                        |  838 ++++++
 arch/i386/xen/kernel/fixup.c                        |   93 
 arch/i386/xen/kernel/head.S                         |  193 +
 arch/i386/xen/kernel/init_task.c                    |   49 
 arch/i386/xen/kernel/io_apic.c                      | 2725 ++++++++++++++++++++
 arch/i386/xen/kernel/ioport.c                       |  121 
 arch/i386/xen/kernel/irq.c                          |  306 ++
 arch/i386/xen/kernel/ldt.c                          |  262 +
 arch/i386/xen/kernel/microcode.c                    |  163 +
 arch/i386/xen/kernel/mpparse.c                      | 1167 ++++++++
 arch/i386/xen/kernel/pci-dma.c                      |  320 ++
 arch/i386/xen/kernel/process.c                      |  837 ++++++
 arch/i386/xen/kernel/quirks.c                       |   49 
 arch/i386/xen/kernel/setup.c                        | 1884 +++++++++++++
 arch/i386/xen/kernel/smp.c                          |  623 ++++
 arch/i386/xen/kernel/swiotlb.c                      |  660 ++++
 arch/i386/xen/kernel/time.c                         |  942 ++++++
 arch/i386/xen/kernel/traps.c                        | 1070 +++++++
 arch/i386/xen/kernel/vsyscall-note.S                |   32 
 arch/i386/xen/kernel/vsyscall.S                     |   15 
 arch/i386/xen/mm/Makefile                           |   24 
 arch/i386/xen/mm/fault.c                            |  628 ++++
 arch/i386/xen/mm/highmem.c                          |  123 
 arch/i386/xen/mm/hypervisor.c                       |  449 +++
 arch/i386/xen/mm/init.c                             |  833 ++++++
 arch/i386/xen/mm/ioremap.c                          |  472 +++
 arch/i386/xen/mm/pgtable.c                          |  598 ++++
 arch/i386/xen/pci/Makefile                          |   31 
 arch/i386/xen/pci/i386.c                            |  295 ++
 arch/i386/xen/pci/irq.c                             | 1193 ++++++++
 arch/um/kernel/physmem.c                            |    4 
 arch/x86_64/Kconfig                                 |   30 
 arch/x86_64/Makefile                                |   31 
 arch/x86_64/ia32/Makefile                           |    4 
 arch/x86_64/ia32/vsyscall-sigreturn.S               |    2 
 arch/x86_64/xen/boot/Makefile                       |   21 
 arch/x86_64/xen/ia32/Makefile                       |   66 
 arch/x86_64/xen/ia32/ia32entry.S                    |  676 ++++
 arch/x86_64/xen/ia32/syscall32.c                    |  128 
 arch/x86_64/xen/ia32/syscall32_syscall.S            |   28 
 arch/x86_64/xen/ia32/vsyscall-int80.S               |   57 
 arch/x86_64/xen/kernel/Makefile                     |   73 
 arch/x86_64/xen/kernel/acpi/Makefile                |   20 
 arch/x86_64/xen/kernel/apic.c                       |  200 +
 arch/x86_64/xen/kernel/e820.c                       |  721 +++++
 arch/x86_64/xen/kernel/early_printk.c               |  308 ++
 arch/x86_64/xen/kernel/entry.S                      | 1137 ++++++++
 arch/x86_64/xen/kernel/genapic.c                    |  144 +
 arch/x86_64/xen/kernel/genapic_xen.c                |  162 +
 arch/x86_64/xen/kernel/head.S                       |  292 ++
 arch/x86_64/xen/kernel/head64.c                     |  127 
 arch/x86_64/xen/kernel/io_apic.c                    | 2115 +++++++++++++++
 arch/x86_64/xen/kernel/ioport.c                     |   57 
 arch/x86_64/xen/kernel/irq.c                        |  158 +
 arch/x86_64/xen/kernel/ldt.c                        |  273 ++
 arch/x86_64/xen/kernel/mpparse.c                    | 1000 +++++++
 arch/x86_64/xen/kernel/pci-nommu.c                  |   98 
 arch/x86_64/xen/kernel/process.c                    |  775 +++++
 arch/x86_64/xen/kernel/setup.c                      | 1576 +++++++++++
 arch/x86_64/xen/kernel/setup64.c                    |  351 ++
 arch/x86_64/xen/kernel/signal.c                     |  513 +++
 arch/x86_64/xen/kernel/smp.c                        |  604 ++++
 arch/x86_64/xen/kernel/traps.c                      |  967 +++++++
 arch/x86_64/xen/kernel/vsyscall.c                   |  241 +
 arch/x86_64/xen/kernel/x8664_ksyms.c                |  209 +
 arch/x86_64/xen/kernel/xen_entry.S                  |   41 
 arch/x86_64/xen/mm/Makefile                         |   29 
 arch/x86_64/xen/mm/fault.c                          |  594 ++++
 arch/x86_64/xen/mm/init.c                           |  974 +++++++
 arch/x86_64/xen/mm/pageattr.c                       |  380 ++
 arch/x86_64/xen/pci/Makefile                        |   38 
 arch/x86_64/xen/pci/Makefile-BUS                    |   22 
 drivers/Kconfig                                     |   11 
 drivers/Makefile                                    |    1 
 drivers/acpi/Kconfig                                |    2 
 drivers/acpi/tables.c                               |    8 
 drivers/char/mem.c                                  |    6 
 drivers/char/tpm/Kconfig                            |   14 
 drivers/char/tpm/Makefile                           |    1 
 drivers/char/tpm/tpm.c                              |   48 
 drivers/char/tpm/tpm.h                              |   13 
 drivers/char/tpm/tpm_atmel.c                        |  102 
 drivers/char/tpm/tpm_nsc.c                          |  149 -
 drivers/char/tpm/tpm_xen.c                          |  525 +++
 drivers/char/tty_io.c                               |    7 
 drivers/serial/Kconfig                              |    2 
 drivers/xen/Kconfig                                 |  179 +
 drivers/xen/Makefile                                |   20 
 drivers/xen/balloon/Makefile                        |    2 
 drivers/xen/balloon/balloon.c                       |  562 ++++
 drivers/xen/blkback/Makefile                        |    2 
 drivers/xen/blkback/blkback.c                       |  541 +++
 drivers/xen/blkback/common.h                        |  116 
 drivers/xen/blkback/interface.c                     |  162 +
 drivers/xen/blkback/vbd.c                           |  103 
 drivers/xen/blkback/xenbus.c                        |  394 ++
 drivers/xen/blkfront/Kconfig                        |    6 
 drivers/xen/blkfront/Makefile                       |    5 
 drivers/xen/blkfront/blkfront.c                     |  814 +++++
 drivers/xen/blkfront/block.h                        |  163 +
 drivers/xen/blkfront/vbd.c                          |  321 ++
 drivers/xen/blktap/Makefile                         |    3 
 drivers/xen/blktap/blktap.c                         |  913 ++++++
 drivers/xen/blktap/common.h                         |  118 
 drivers/xen/blktap/interface.c                      |  147 +
 drivers/xen/blktap/xenbus.c                         |  234 +
 drivers/xen/char/Makefile                           |    2 
 drivers/xen/char/mem.c                              |  157 +
 drivers/xen/console/Makefile                        |    2 
 drivers/xen/console/console.c                       |  705 +++++
 drivers/xen/console/xencons_ring.c                  |  131 
 drivers/xen/console/xencons_ring.h                  |   23 
 drivers/xen/core/Makefile                           |    9 
 drivers/xen/core/evtchn.c                           |  783 +++++
 drivers/xen/core/gnttab.c                           |  474 +++
 drivers/xen/core/reboot.c                           |  428 +++
 drivers/xen/core/skbuff.c                           |  143 +
 drivers/xen/core/smpboot.c                          |  439 +++
 drivers/xen/core/xen_proc.c                         |   29 
 drivers/xen/evtchn/Makefile                         |    2 
 drivers/xen/evtchn/evtchn.c                         |  479 +++
 drivers/xen/net_driver_util.c                       |   67 
 drivers/xen/netback/Makefile                        |    2 
 drivers/xen/netback/common.h                        |  118 
 drivers/xen/netback/interface.c                     |  307 ++
 drivers/xen/netback/loopback.c                      |  189 +
 drivers/xen/netback/netback.c                       |  823 ++++++
 drivers/xen/netback/xenbus.c                        |  329 ++
 drivers/xen/netfront/Kconfig                        |    6 
 drivers/xen/netfront/Makefile                       |    4 
 drivers/xen/netfront/netfront.c                     | 1454 ++++++++++
 drivers/xen/privcmd/Makefile                        |    2 
 drivers/xen/privcmd/privcmd.c                       |  257 +
 drivers/xen/tpmback/Makefile                        |    4 
 drivers/xen/tpmback/common.h                        |  101 
 drivers/xen/tpmback/interface.c                     |  200 +
 drivers/xen/tpmback/tpmback.c                       | 1109 ++++++++
 drivers/xen/tpmback/xenbus.c                        |  329 ++
 drivers/xen/tpmfront/Makefile                       |    2 
 drivers/xen/tpmfront/tpmfront.c                     |  731 +++++
 drivers/xen/tpmfront/tpmfront.h                     |   48 
 drivers/xen/util.c                                  |   75 
 drivers/xen/xenbus/Makefile                         |    8 
 drivers/xen/xenbus/xenbus_client.c                  |  256 +
 drivers/xen/xenbus/xenbus_comms.c                   |  203 +
 drivers/xen/xenbus/xenbus_comms.h                   |   50 
 drivers/xen/xenbus/xenbus_dev.c                     |  241 +
 drivers/xen/xenbus/xenbus_probe.c                   | 1001 +++++++
 drivers/xen/xenbus/xenbus_xs.c                      |  827 ++++++
 fs/Kconfig                                          |    1 
 include/asm-i386/atomic.h                           |    7 
 include/asm-i386/bitops.h                           |   19 
 include/asm-i386/futex.h                            |    4 
 include/asm-i386/mach-xen/asm/agp.h                 |   37 
 include/asm-i386/mach-xen/asm/bug.h                 |   16 
 include/asm-i386/mach-xen/asm/desc.h                |  164 +
 include/asm-i386/mach-xen/asm/dma-mapping.h         |  156 +
 include/asm-i386/mach-xen/asm/fixmap.h              |  168 +
 include/asm-i386/mach-xen/asm/floppy.h              |  147 +
 include/asm-i386/mach-xen/asm/highmem.h             |   81 
 include/asm-i386/mach-xen/asm/hw_irq.h              |   73 
 include/asm-i386/mach-xen/asm/hypercall.h           |  313 ++
 include/asm-i386/mach-xen/asm/hypervisor.h          |  175 +
 include/asm-i386/mach-xen/asm/io.h                  |  436 +++
 include/asm-i386/mach-xen/asm/kmap_types.h          |   32 
 include/asm-i386/mach-xen/asm/mmu.h                 |   21 
 include/asm-i386/mach-xen/asm/mmu_context.h         |  106 
 include/asm-i386/mach-xen/asm/page.h                |  270 +
 include/asm-i386/mach-xen/asm/param.h               |   25 
 include/asm-i386/mach-xen/asm/pci.h                 |  150 +
 include/asm-i386/mach-xen/asm/pgalloc.h             |   64 
 include/asm-i386/mach-xen/asm/pgtable-2level-defs.h |   21 
 include/asm-i386/mach-xen/asm/pgtable-2level.h      |  122 
 include/asm-i386/mach-xen/asm/pgtable-3level-defs.h |   25 
 include/asm-i386/mach-xen/asm/pgtable-3level.h      |  203 +
 include/asm-i386/mach-xen/asm/pgtable.h             |  520 +++
 include/asm-i386/mach-xen/asm/processor.h           |  735 +++++
 include/asm-i386/mach-xen/asm/ptrace.h              |   87 
 include/asm-i386/mach-xen/asm/scatterlist.h         |   22 
 include/asm-i386/mach-xen/asm/segment.h             |   99 
 include/asm-i386/mach-xen/asm/setup.h               |   66 
 include/asm-i386/mach-xen/asm/smp.h                 |  103 
 include/asm-i386/mach-xen/asm/spinlock.h            |  217 +
 include/asm-i386/mach-xen/asm/swiotlb.h             |   42 
 include/asm-i386/mach-xen/asm/synch_bitops.h        |  140 +
 include/asm-i386/mach-xen/asm/system.h              |  667 ++++
 include/asm-i386/mach-xen/asm/tlbflush.h            |  102 
 include/asm-i386/mach-xen/asm/vga.h                 |   20 
 include/asm-i386/mach-xen/irq_vectors.h             |  125 
 include/asm-i386/mach-xen/setup_arch_post.h         |   40 
 include/asm-i386/mach-xen/setup_arch_pre.h          |    5 
 include/asm-i386/rwsem.h                            |   17 
 include/asm-i386/smp_alt.h                          |   32 
 include/asm-i386/spinlock.h                         |   39 
 include/asm-i386/system.h                           |   58 
 include/asm-um/page.h                               |    2 
 include/asm-x86_64/mach-xen/asm/arch_hooks.h        |   27 
 include/asm-x86_64/mach-xen/asm/bootsetup.h         |   42 
 include/asm-x86_64/mach-xen/asm/desc.h              |  252 +
 include/asm-x86_64/mach-xen/asm/dma-mapping.h       |    1 
 include/asm-x86_64/mach-xen/asm/fixmap.h            |  114 
 include/asm-x86_64/mach-xen/asm/floppy.h            |  204 +
 include/asm-x86_64/mach-xen/asm/hw_irq.h            |  141 +
 include/asm-x86_64/mach-xen/asm/hypercall.h         |  320 ++
 include/asm-x86_64/mach-xen/asm/hypervisor.h        |    2 
 include/asm-x86_64/mach-xen/asm/io.h                |  357 ++
 include/asm-x86_64/mach-xen/asm/irq.h               |   39 
 include/asm-x86_64/mach-xen/asm/mmu.h               |   33 
 include/asm-x86_64/mach-xen/asm/mmu_context.h       |  130 
 include/asm-x86_64/mach-xen/asm/page.h              |  255 +
 include/asm-x86_64/mach-xen/asm/param.h             |   24 
 include/asm-x86_64/mach-xen/asm/pci.h               |  177 +
 include/asm-x86_64/mach-xen/asm/pgalloc.h           |  198 +
 include/asm-x86_64/mach-xen/asm/pgtable.h           |  594 ++++
 include/asm-x86_64/mach-xen/asm/processor.h         |  505 +++
 include/asm-x86_64/mach-xen/asm/ptrace.h            |  125 
 include/asm-x86_64/mach-xen/asm/segment.h           |   46 
 include/asm-x86_64/mach-xen/asm/smp.h               |  150 +
 include/asm-x86_64/mach-xen/asm/synch_bitops.h      |    2 
 include/asm-x86_64/mach-xen/asm/system.h            |  411 +++
 include/asm-x86_64/mach-xen/asm/timer.h             |   67 
 include/asm-x86_64/mach-xen/asm/tlbflush.h          |  104 
 include/asm-x86_64/mach-xen/asm/vga.h               |   20 
 include/asm-x86_64/mach-xen/asm/xor.h               |  328 ++
 include/asm-x86_64/mach-xen/io_ports.h              |   30 
 include/asm-x86_64/mach-xen/irq_vectors.h           |  123 
 include/asm-x86_64/mach-xen/mach_time.h             |  122 
 include/asm-x86_64/mach-xen/mach_timer.h            |   48 
 include/asm-x86_64/mach-xen/setup_arch_post.h       |   47 
 include/asm-x86_64/mach-xen/setup_arch_pre.h        |    5 
 include/asm-xen/balloon.h                           |   70 
 include/asm-xen/driver_util.h                       |   26 
 include/asm-xen/evtchn.h                            |  147 +
 include/asm-xen/foreign_page.h                      |   40 
 include/asm-xen/gnttab.h                            |   98 
 include/asm-xen/linux-public/evtchn.h               |   98 
 include/asm-xen/linux-public/privcmd.h              |   91 
 include/asm-xen/linux-public/xenstored.h            |   89 
 include/asm-xen/net_driver_util.h                   |   56 
 include/asm-xen/tpmfe.h                             |   33 
 include/asm-xen/xen-public/acm.h                    |  198 +
 include/asm-xen/xen-public/acm_ops.h                |  107 
 include/asm-xen/xen-public/arch-ia64.h              |  279 ++
 include/asm-xen/xen-public/arch-x86_32.h            |  152 +
 include/asm-xen/xen-public/arch-x86_64.h            |  221 +
 include/asm-xen/xen-public/dom0_ops.h               |  473 +++
 include/asm-xen/xen-public/event_channel.h          |  190 +
 include/asm-xen/xen-public/grant_table.h            |  299 ++
 include/asm-xen/xen-public/io/blkif.h               |   84 
 include/asm-xen/xen-public/io/console.h             |   33 
 include/asm-xen/xen-public/io/ioreq.h               |   91 
 include/asm-xen/xen-public/io/netif.h               |  103 
 include/asm-xen/xen-public/io/ring.h                |  209 +
 include/asm-xen/xen-public/io/tpmif.h               |   54 
 include/asm-xen/xen-public/io/vmx_vlapic.h          |   58 
 include/asm-xen/xen-public/io/vmx_vpic.h            |   85 
 include/asm-xen/xen-public/io/xenbus.h              |   66 
 include/asm-xen/xen-public/io/xs_wire.h             |  118 
 include/asm-xen/xen-public/memory.h                 |  101 
 include/asm-xen/xen-public/physdev.h                |   70 
 include/asm-xen/xen-public/sched.h                  |   60 
 include/asm-xen/xen-public/sched_ctl.h              |   68 
 include/asm-xen/xen-public/trace.h                  |   90 
 include/asm-xen/xen-public/vcpu.h                   |   64 
 include/asm-xen/xen-public/version.h                |   52 
 include/asm-xen/xen-public/vmx_assist.h             |  110 
 include/asm-xen/xen-public/xen.h                    |  445 +++
 include/asm-xen/xen_proc.h                          |   23 
 include/asm-xen/xenbus.h                            |  252 +
 include/asm-xen/xencons.h                           |    7 
 include/linux/gfp.h                                 |    6 
 include/linux/highmem.h                             |    6 
 include/linux/irq.h                                 |    3 
 include/linux/mm.h                                  |   10 
 include/linux/skbuff.h                              |   13 
 kernel/Kconfig.preempt                              |    1 
 kernel/irq/manage.c                                 |   84 
 lib/Kconfig.debug                                   |    2 
 lib/Makefile                                        |    2 
 mm/Kconfig                                          |    3 
 mm/highmem.c                                        |   11 
 mm/memory.c                                         |  118 
 mm/mmap.c                                           |    4 
 mm/page_alloc.c                                     |    6 
 net/core/dev.c                                      |   45 
 net/core/skbuff.c                                   |   36 
 304 files changed, 69029 insertions(+), 243 deletions(-)

--- NEW FILE linux-2.6-xen-merge.patch ---
Merge with upstream linux-2.6-merge.hg
---

 arch/i386/Kconfig                                  |   54 
 arch/i386/Makefile                                 |   38 
 arch/i386/kernel/Makefile                          |    1 
 arch/i386/kernel/smpalts.c                         |   85 +
 arch/i386/kernel/smpboot.c                         |   10 
 arch/i386/kernel/vmlinux.lds.S                     |    7 
 arch/i386/mach-xen/Makefile                        |   13 
 arch/i386/mach-xen/setup.c                         |   37 
 arch/i386/xen/boot/Makefile                        |   21 
 arch/i386/xen/kernel/Makefile                      |   99 +
 arch/i386/xen/kernel/acpi/Makefile                 |   17 
 arch/i386/xen/kernel/acpi/boot.c                   | 1157 ++++++++
 arch/i386/xen/kernel/apic.c                        |   89 +
 arch/i386/xen/kernel/cpu/Makefile                  |   31 
 arch/i386/xen/kernel/cpu/common.c                  |  655 +++++
 arch/i386/xen/kernel/cpu/mtrr/Makefile             |   16 
 arch/i386/xen/kernel/cpu/mtrr/main.c               |  180 +
 arch/i386/xen/kernel/early_printk.c                |    1 
 arch/i386/xen/kernel/entry.S                       |  838 ++++++
 arch/i386/xen/kernel/fixup.c                       |   93 +
 arch/i386/xen/kernel/head.S                        |  193 +
 arch/i386/xen/kernel/init_task.c                   |   49 
 arch/i386/xen/kernel/io_apic.c                     | 2725 ++++++++++++++++++++
 arch/i386/xen/kernel/ioport.c                      |  121 +
 arch/i386/xen/kernel/irq.c                         |  306 ++
 arch/i386/xen/kernel/ldt.c                         |  262 ++
 arch/i386/xen/kernel/microcode.c                   |  163 +
 arch/i386/xen/kernel/mpparse.c                     | 1167 +++++++++
 arch/i386/xen/kernel/pci-dma.c                     |  320 ++
 arch/i386/xen/kernel/process.c                     |  837 ++++++
 arch/i386/xen/kernel/quirks.c                      |   49 
 arch/i386/xen/kernel/setup.c                       | 1884 ++++++++++++++
 arch/i386/xen/kernel/smp.c                         |  623 +++++
 arch/i386/xen/kernel/swiotlb.c                     |  660 +++++
 arch/i386/xen/kernel/time.c                        |  942 +++++++
 arch/i386/xen/kernel/traps.c                       | 1070 ++++++++
 arch/i386/xen/kernel/vsyscall-note.S               |   32 
 arch/i386/xen/kernel/vsyscall.S                    |   15 
 arch/i386/xen/mm/Makefile                          |   24 
 arch/i386/xen/mm/fault.c                           |  628 +++++
 arch/i386/xen/mm/highmem.c                         |  123 +
 arch/i386/xen/mm/hypervisor.c                      |  449 +++
 arch/i386/xen/mm/init.c                            |  833 ++++++
 arch/i386/xen/mm/ioremap.c                         |  472 +++
 arch/i386/xen/mm/pgtable.c                         |  598 ++++
 arch/i386/xen/pci/Makefile                         |   31 
 arch/i386/xen/pci/i386.c                           |  295 ++
 arch/i386/xen/pci/irq.c                            | 1193 +++++++++
 arch/um/kernel/physmem.c                           |    4 
 arch/x86_64/Kconfig                                |   30 
 arch/x86_64/Makefile                               |   31 
 arch/x86_64/ia32/Makefile                          |    4 
 arch/x86_64/ia32/vsyscall-sigreturn.S              |    2 
 arch/x86_64/xen/boot/Makefile                      |   21 
 arch/x86_64/xen/ia32/Makefile                      |   66 
 arch/x86_64/xen/ia32/ia32entry.S                   |  676 +++++
 arch/x86_64/xen/ia32/syscall32.c                   |  128 +
 arch/x86_64/xen/ia32/syscall32_syscall.S           |   28 
 arch/x86_64/xen/ia32/vsyscall-int80.S              |   57 
 arch/x86_64/xen/kernel/Makefile                    |   73 +
 arch/x86_64/xen/kernel/acpi/Makefile               |   20 
 arch/x86_64/xen/kernel/apic.c                      |  200 +
 arch/x86_64/xen/kernel/e820.c                      |  721 +++++
 arch/x86_64/xen/kernel/early_printk.c              |  308 ++
 arch/x86_64/xen/kernel/entry.S                     | 1137 ++++++++
 arch/x86_64/xen/kernel/genapic.c                   |  144 +
 arch/x86_64/xen/kernel/genapic_xen.c               |  162 +
 arch/x86_64/xen/kernel/head.S                      |  292 ++
 arch/x86_64/xen/kernel/head64.c                    |  127 +
 arch/x86_64/xen/kernel/io_apic.c                   | 2115 ++++++++++++++++
 arch/x86_64/xen/kernel/ioport.c                    |   57 
 arch/x86_64/xen/kernel/irq.c                       |  158 +
 arch/x86_64/xen/kernel/ldt.c                       |  273 ++
 arch/x86_64/xen/kernel/mpparse.c                   | 1000 +++++++
 arch/x86_64/xen/kernel/pci-nommu.c                 |   98 +
 arch/x86_64/xen/kernel/process.c                   |  775 ++++++
 arch/x86_64/xen/kernel/setup.c                     | 1576 ++++++++++++
 arch/x86_64/xen/kernel/setup64.c                   |  351 +++
 arch/x86_64/xen/kernel/signal.c                    |  513 ++++
 arch/x86_64/xen/kernel/smp.c                       |  604 ++++
 arch/x86_64/xen/kernel/traps.c                     |  967 +++++++
 arch/x86_64/xen/kernel/vsyscall.c                  |  241 ++
 arch/x86_64/xen/kernel/x8664_ksyms.c               |  209 ++
 arch/x86_64/xen/kernel/xen_entry.S                 |   41 
 arch/x86_64/xen/mm/Makefile                        |   29 
 arch/x86_64/xen/mm/fault.c                         |  594 ++++
 arch/x86_64/xen/mm/init.c                          |  974 +++++++
 arch/x86_64/xen/mm/pageattr.c                      |  380 +++
 arch/x86_64/xen/pci/Makefile                       |   38 
 arch/x86_64/xen/pci/Makefile-BUS                   |   22 
 drivers/Kconfig                                    |   11 
 drivers/Makefile                                   |    1 
 drivers/acpi/Kconfig                               |    2 
 drivers/acpi/tables.c                              |    8 
 drivers/char/mem.c                                 |    6 
 drivers/char/tpm/Kconfig                           |   14 
 drivers/char/tpm/Makefile                          |    1 
 drivers/char/tpm/tpm.c                             |   48 
 drivers/char/tpm/tpm.h                             |   13 
 drivers/char/tpm/tpm_atmel.c                       |  102 -
 drivers/char/tpm/tpm_nsc.c                         |  149 +
 drivers/char/tpm/tpm_xen.c                         |  525 ++++
 drivers/char/tty_io.c                              |    7 
 drivers/serial/Kconfig                             |    2 
 drivers/xen/Kconfig                                |  179 +
 drivers/xen/Makefile                               |   20 
 drivers/xen/balloon/Makefile                       |    2 
 drivers/xen/balloon/balloon.c                      |  562 ++++
 drivers/xen/blkback/Makefile                       |    2 
 drivers/xen/blkback/blkback.c                      |  541 ++++
 drivers/xen/blkback/common.h                       |  116 +
 drivers/xen/blkback/interface.c                    |  162 +
 drivers/xen/blkback/vbd.c                          |  103 +
 drivers/xen/blkback/xenbus.c                       |  394 +++
 drivers/xen/blkfront/Kconfig                       |    6 
 drivers/xen/blkfront/Makefile                      |    5 
 drivers/xen/blkfront/blkfront.c                    |  814 ++++++
 drivers/xen/blkfront/block.h                       |  163 +
 drivers/xen/blkfront/vbd.c                         |  321 ++
 drivers/xen/blktap/Makefile                        |    3 
 drivers/xen/blktap/blktap.c                        |  913 +++++++
 drivers/xen/blktap/common.h                        |  118 +
 drivers/xen/blktap/interface.c                     |  147 +
 drivers/xen/blktap/xenbus.c                        |  234 ++
 drivers/xen/char/Makefile                          |    2 
 drivers/xen/char/mem.c                             |  157 +
 drivers/xen/console/Makefile                       |    2 
 drivers/xen/console/console.c                      |  705 +++++
 drivers/xen/console/xencons_ring.c                 |  131 +
 drivers/xen/console/xencons_ring.h                 |   23 
 drivers/xen/core/Makefile                          |    9 
 drivers/xen/core/evtchn.c                          |  783 ++++++
 drivers/xen/core/gnttab.c                          |  474 +++
 drivers/xen/core/reboot.c                          |  428 +++
 drivers/xen/core/skbuff.c                          |  143 +
 drivers/xen/core/smpboot.c                         |  439 +++
 drivers/xen/core/xen_proc.c                        |   29 
 drivers/xen/evtchn/Makefile                        |    2 
 drivers/xen/evtchn/evtchn.c                        |  479 ++++
 drivers/xen/net_driver_util.c                      |   67 
 drivers/xen/netback/Makefile                       |    2 
 drivers/xen/netback/common.h                       |  118 +
 drivers/xen/netback/interface.c                    |  307 ++
 drivers/xen/netback/loopback.c                     |  189 +
 drivers/xen/netback/netback.c                      |  823 ++++++
 drivers/xen/netback/xenbus.c                       |  329 ++
 drivers/xen/netfront/Kconfig                       |    6 
 drivers/xen/netfront/Makefile                      |    4 
 drivers/xen/netfront/netfront.c                    | 1454 +++++++++++
 drivers/xen/privcmd/Makefile                       |    2 
 drivers/xen/privcmd/privcmd.c                      |  257 ++
 drivers/xen/tpmback/Makefile                       |    4 
 drivers/xen/tpmback/common.h                       |  101 +
 drivers/xen/tpmback/interface.c                    |  200 +
 drivers/xen/tpmback/tpmback.c                      | 1109 ++++++++
 drivers/xen/tpmback/xenbus.c                       |  329 ++
 drivers/xen/tpmfront/Makefile                      |    2 
 drivers/xen/tpmfront/tpmfront.c                    |  731 +++++
 drivers/xen/tpmfront/tpmfront.h                    |   48 
 drivers/xen/util.c                                 |   75 +
 drivers/xen/xenbus/Makefile                        |    8 
 drivers/xen/xenbus/xenbus_client.c                 |  256 ++
 drivers/xen/xenbus/xenbus_comms.c                  |  203 +
 drivers/xen/xenbus/xenbus_comms.h                  |   50 
 drivers/xen/xenbus/xenbus_dev.c                    |  241 ++
 drivers/xen/xenbus/xenbus_probe.c                  | 1001 +++++++
 drivers/xen/xenbus/xenbus_xs.c                     |  827 ++++++
 fs/Kconfig                                         |    1 
 include/asm-i386/atomic.h                          |    7 
 include/asm-i386/bitops.h                          |   19 
 include/asm-i386/futex.h                           |    4 
 include/asm-i386/mach-xen/asm/agp.h                |   37 
 include/asm-i386/mach-xen/asm/bug.h                |   16 
 include/asm-i386/mach-xen/asm/desc.h               |  164 +
 include/asm-i386/mach-xen/asm/dma-mapping.h        |  156 +
 include/asm-i386/mach-xen/asm/fixmap.h             |  168 +
 include/asm-i386/mach-xen/asm/floppy.h             |  147 +
 include/asm-i386/mach-xen/asm/highmem.h            |   81 +
 include/asm-i386/mach-xen/asm/hw_irq.h             |   73 +
 include/asm-i386/mach-xen/asm/hypercall.h          |  313 ++
 include/asm-i386/mach-xen/asm/hypervisor.h         |  175 +
 include/asm-i386/mach-xen/asm/io.h                 |  436 +++
 include/asm-i386/mach-xen/asm/kmap_types.h         |   32 
 include/asm-i386/mach-xen/asm/mmu.h                |   21 
 include/asm-i386/mach-xen/asm/mmu_context.h        |  106 +
 include/asm-i386/mach-xen/asm/page.h               |  270 ++
 include/asm-i386/mach-xen/asm/param.h              |   25 
 include/asm-i386/mach-xen/asm/pci.h                |  150 +
 include/asm-i386/mach-xen/asm/pgalloc.h            |   64 
 .../asm-i386/mach-xen/asm/pgtable-2level-defs.h    |   21 
 include/asm-i386/mach-xen/asm/pgtable-2level.h     |  122 +
 .../asm-i386/mach-xen/asm/pgtable-3level-defs.h    |   25 
 include/asm-i386/mach-xen/asm/pgtable-3level.h     |  203 +
 include/asm-i386/mach-xen/asm/pgtable.h            |  520 ++++
 include/asm-i386/mach-xen/asm/processor.h          |  735 +++++
 include/asm-i386/mach-xen/asm/ptrace.h             |   87 +
[...72131 lines suppressed...]
diff --git a/mm/mmap.c b/mm/mmap.c
index 3fce667..c77acaa 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2024,6 +2024,10 @@ void exit_mmap(struct mm_struct *mm)
 	unsigned long nr_accounted = 0;
 	unsigned long end;
 
+#ifdef arch_exit_mmap
+	arch_exit_mmap(mm);
+#endif
+
 	lru_add_drain();
 	flush_cache_mm(mm);
 	tlb = tlb_gather_mmu(mm, 1);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ce1be4e..8d530da 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -399,7 +399,8 @@ void __free_pages_ok(struct page *page, 
 	int i;
 	int reserved = 0;
 
-	arch_free_page(page, order);
+	if (arch_free_page(page, order))
+		return;
 
 #ifndef CONFIG_MMU
 	if (order > 0)
@@ -683,7 +684,8 @@ static void fastcall free_hot_cold_page(
 	struct per_cpu_pages *pcp;
 	unsigned long flags;
 
-	arch_free_page(page, 0);
+	if (arch_free_page(page, 0))
+		return;
 
 	if (PageAnon(page))
 		page->mapping = NULL;
diff --git a/net/core/dev.c b/net/core/dev.c
index 0b48e29..d20064c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -115,6 +115,12 @@
 #endif	/* CONFIG_NET_RADIO */
 #include <asm/current.h>
 
+#ifdef CONFIG_XEN
+#include <net/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#endif
+
 /*
  *	The list of packet types we will receive (as opposed to discard)
  *	and the routines to invoke.
@@ -1261,6 +1267,32 @@ int dev_queue_xmit(struct sk_buff *skb)
 	    __skb_linearize(skb, GFP_ATOMIC))
 		goto out_kfree_skb;
 
+#ifdef CONFIG_XEN
+	/* If a checksum-deferred packet is forwarded to a device that needs a
+	 * checksum, correct the pointers and force checksumming.
+	 */
+	if (skb->proto_csum_blank) {
+		if (skb->protocol != htons(ETH_P_IP))
+			goto out_kfree_skb;
+		skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
+		if (skb->h.raw >= skb->tail)
+			goto out_kfree_skb;
+		switch (skb->nh.iph->protocol) {
+		case IPPROTO_TCP:
+			skb->csum = offsetof(struct tcphdr, check);
+			break;
+		case IPPROTO_UDP:
+			skb->csum = offsetof(struct udphdr, check);
+			break;
+		default:
+			goto out_kfree_skb;
+		}
+		if ((skb->h.raw + skb->csum + 2) > skb->tail)
+			goto out_kfree_skb;
+		skb->ip_summed = CHECKSUM_HW;
+	}
+#endif
+
 	/* If packet is not checksummed and device does not support
 	 * checksumming for this protocol, complete checksumming here.
 	 */
@@ -1610,6 +1642,19 @@ int netif_receive_skb(struct sk_buff *sk
 	}
 #endif
 
+#ifdef CONFIG_XEN
+	switch (skb->ip_summed) {
+	case CHECKSUM_UNNECESSARY:
+		skb->proto_csum_valid = 1;
+		break;
+	case CHECKSUM_HW:
+		/* XXX Implement me. */
+	default:
+		skb->proto_csum_valid = 0;
+		break;
+	}
+#endif
+
 	list_for_each_entry_rcu(ptype, &ptype_all, list) {
 		if (!ptype->dev || ptype->dev == skb->dev) {
 			if (pt_prev) 
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index b7d13a4..a6ac62d 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -132,6 +132,7 @@ void skb_under_panic(struct sk_buff *skb
  *	Buffers may only be allocated from interrupts using a @gfp_mask of
  *	%GFP_ATOMIC.
  */
+#ifndef CONFIG_HAVE_ARCH_ALLOC_SKB
 struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
 			    int fclone)
 {
@@ -181,10 +182,14 @@ struct sk_buff *__alloc_skb(unsigned int
 out:
 	return skb;
 nodata:
-	kmem_cache_free(skbuff_head_cache, skb);
+	if (fclone)
+		kmem_cache_free(skbuff_fclone_cache, skb);
+	else
+		kmem_cache_free(skbuff_head_cache, skb);
 	skb = NULL;
 	goto out;
 }
+#endif /* !CONFIG_HAVE_ARCH_ALLOC_SKB */
 
 /**
  *	alloc_skb_from_cache	-	allocate a network buffer
@@ -202,14 +207,20 @@ nodata:
  */
 struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
 				     unsigned int size,
-				     gfp_t gfp_mask)
+				     gfp_t gfp_mask,
+				     int fclone)
 {
 	struct sk_buff *skb;
 	u8 *data;
 
 	/* Get the HEAD */
-	skb = kmem_cache_alloc(skbuff_head_cache,
-			       gfp_mask & ~__GFP_DMA);
+	if (fclone)
+		skb = kmem_cache_alloc(skbuff_fclone_cache,
+				       gfp_mask & ~__GFP_DMA);
+	else
+		skb = kmem_cache_alloc(skbuff_head_cache,
+				       gfp_mask & ~__GFP_DMA);
+
 	if (!skb)
 		goto out;
 
@@ -226,7 +237,15 @@ struct sk_buff *alloc_skb_from_cache(kme
 	skb->data = data;
 	skb->tail = data;
 	skb->end  = data + size;
+	if (fclone) {
+		struct sk_buff *child = skb + 1;
+		atomic_t *fclone_ref = (atomic_t *) (child + 1);
+
+		skb->fclone = SKB_FCLONE_ORIG;
+		atomic_set(fclone_ref, 1);
 
+		child->fclone = SKB_FCLONE_UNAVAILABLE;
+	}
 	atomic_set(&(skb_shinfo(skb)->dataref), 1);
 	skb_shinfo(skb)->nr_frags  = 0;
 	skb_shinfo(skb)->tso_size = 0;
@@ -235,7 +254,10 @@ struct sk_buff *alloc_skb_from_cache(kme
 out:
 	return skb;
 nodata:
-	kmem_cache_free(skbuff_head_cache, skb);
+	if (fclone)
+		kmem_cache_free(skbuff_fclone_cache, skb);
+	else
+		kmem_cache_free(skbuff_head_cache, skb);
 	skb = NULL;
 	goto out;
 }
@@ -407,6 +429,10 @@ struct sk_buff *skb_clone(struct sk_buff
 	C(local_df);
 	n->cloned = 1;
 	n->nohdr = 0;
+#ifdef CONFIG_XEN
+	C(proto_csum_valid);
+	C(proto_csum_blank);
+#endif
 	C(pkt_type);
 	C(ip_summed);
 	C(priority);

linux-2.6-xen-no-tls-warn.patch:
 fixup.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-xen-no-tls-warn.patch ---
diff --git a/arch/i386/xen/kernel/fixup.c b/arch/i386/xen/kernel/fixup.c
index ccfb39d..26a5a18 100644
--- a/arch/i386/xen/kernel/fixup.c
+++ b/arch/i386/xen/kernel/fixup.c
@@ -39,7 +39,7 @@
 
 fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
 {
-	static unsigned long printed = 0;
+	static unsigned long printed = 1;
 	char info[100];
 	int i;
 

linux-2.6-xen-vdso-note.patch:
 linux-2.6.11/include/asm-xen/asm-i386/page.h   |    2 +
 linux-2.6.12/arch/xen/i386/kernel/Makefile     |    6 ++--
 linux-2.6.12/arch/xen/i386/kernel/ldt.c        |    3 +-
 linux-2.6/arch/xen/i386/kernel/vsyscall-note.S |   32 +++++++++++++++++++++++++
 4 files changed, 39 insertions(+), 4 deletions(-)

--- NEW FILE linux-2.6-xen-vdso-note.patch ---
--- linux-2.6/arch/xen/i386/kernel/vsyscall-note.S
+++ linux-2.6/arch/xen/i386/kernel/vsyscall-note.S
@@ -0,0 +1,32 @@
+/*
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ * First we get the vanilla i386 note that supplies the kernel version info.
+ */
+
+#include "../../../i386/kernel/vsyscall-note.S"
+
+/*
+ * Now we add a special note telling glibc's dynamic linker a fake hardware
+ * flavor that it will use to choose the search path for libraries in the
+ * same way it uses real hardware capabilities like "mmx".
+ * We supply "nosegneg" as the fake capability, to indicate that we
+ * do not like negative offsets in instructions using segment overrides,
+ * since we implement those inefficiently.  This makes it possible to
+ * install libraries optimized to avoid those access patterns in someplace
+ * like /lib/i686/tls/nosegneg.  Note that an /etc/ld.so.conf.d/file
+ * corresponding to the bits here is needed to make ldconfig work right.
+ * It should contain:
+ *	hwcap 0 nosegneg
+ * to match the mapping of bit to name that we give here.
+ */
+#define NOTE_KERNELCAP_BEGIN(ncaps, mask) \
+	ASM_ELF_NOTE_BEGIN(".note.kernelcap", "a", "GNU", 2) \
+	.long ncaps, mask
+#define NOTE_KERNELCAP(bit, name) \
+	.byte bit; .asciz name
+#define NOTE_KERNELCAP_END ASM_ELF_NOTE_END
+
+NOTE_KERNELCAP_BEGIN(1, 1)
+NOTE_KERNELCAP(0, "nosegneg")
+NOTE_KERNELCAP_END
--- linux-2.6.11/include/asm-xen/asm-i386/page.h.vdso	2005-04-27 10:33:03.000000000 -0400
+++ linux-2.6.11/include/asm-xen/asm-i386/page.h	2005-04-27 10:33:19.000000000 -0400
@@ -200,6 +200,8 @@ extern int sysctl_legacy_va_layout;
 
 #define devmem_is_allowed(x) 1
 
+#define __HAVE_ARCH_GATE_AREA 1
+
 #endif /* __KERNEL__ */
 
 #endif /* _I386_PAGE_H */
--- linux-2.6.12/arch/xen/i386/kernel/ldt.c.vdso	2005-08-19 10:50:02.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/ldt.c	2005-08-21 11:01:21.000000000 -0400
@@ -101,8 +101,9 @@
 	struct mm_struct * old_mm;
 	int retval = 0;
 
-	memset(&mm->context, 0, sizeof(mm->context));
 	init_MUTEX(&mm->context.sem);
+	mm->context.size = 0;
+	mm->context.pinned = 0;
 	old_mm = current->mm;
 	if (old_mm && old_mm->context.size > 0) {
 		down(&old_mm->context.sem);
--- linux-2.6.12/arch/xen/i386/kernel/Makefile.vdso	2005-08-22 13:38:36.000000000 -0400
+++ linux-2.6.12/arch/xen/i386/kernel/Makefile	2005-08-22 13:42:00.000000000 -0400
@@ -69,7 +69,7 @@
 
 $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \
 $(obj)/vsyscall-%.so: $(src)/vsyscall.lds \
-		      $(obj)/vsyscall-%.o FORCE
+		      $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE
 	$(call if_changed,syscall)
 
 # We also create a special relocatable object that should mirror the symbol
@@ -81,11 +81,11 @@
 
 SYSCFLAGS_vsyscall-syms.o = -r
 $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
-			$(obj)/vsyscall-sysenter.o FORCE
+			$(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE
 	$(call if_changed,syscall)
 
 c-link	:=
-s-link	:= vsyscall-int80.o vsyscall-sysenter.o vsyscall-sigreturn.o vsyscall.lds.o syscall_table.o
+s-link	:= vsyscall-int80.o vsyscall-sysenter.o vsyscall-sigreturn.o vsyscall.lds.o vsyscall-note.o syscall_table.o
 
 $(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-obj-m) $(c-link)) $(patsubst %.o,$(obj)/%.S,$(s-obj-y) $(s-link)):
 	@ln -fsn $(srctree)/arch/i386/kernel/$(notdir $@) $@

linux-2.6.14-intel-cache-build.patch:
 intel_cacheinfo.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6.14-intel-cache-build.patch ---
--- linux-2.6.14/arch/i386/kernel/cpu/intel_cacheinfo.c.orig	2005-11-02 11:25:14.000000000 +0000
+++ linux-2.6.14/arch/i386/kernel/cpu/intel_cacheinfo.c	2005-11-02 11:25:23.000000000 +0000
@@ -569,7 +569,7 @@ static int __cpuinit cache_add_dev(struc
 	return retval;
 }
 
-static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
+static void cache_remove_dev(struct sys_device * sys_dev)
 {
 	unsigned int cpu = sys_dev->id;
 	unsigned long i;

linux-2.6.14-kauditd-suspend.patch:
 audit.c |    4 ++++
 1 files changed, 4 insertions(+)

--- NEW FILE linux-2.6.14-kauditd-suspend.patch ---
--- linux-2.6.14/kernel/audit.c.orig	2005-11-02 08:45:20.000000000 +0000
+++ linux-2.6.14/kernel/audit.c	2005-11-02 08:44:41.000000000 +0000
@@ -288,6 +288,10 @@ int kauditd_thread(void *dummy)
 			}
 		} else {
 			DECLARE_WAITQUEUE(wait, current);
+
+			if (try_to_freeze())
+				continue;
+
 			set_current_state(TASK_INTERRUPTIBLE);
 			add_wait_queue(&kauditd_wait, &wait);
 


--- NEW FILE linux-2.6.14.tar.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBDYX2OyGugalF9Dw4RAmN2AJoDiT+pAFm/vF+DFdnQiJHDAEuA7gCfezwl
4KyLPnQ1WTwWg0G5h9VFouo=
=AIgg
-----END PGP SIGNATURE-----

linux-2.6.15-cell-bogus-console-fix.patch:
 bogus_console.c |   41 +++++++++++++++++++----------------------
 1 files changed, 19 insertions(+), 22 deletions(-)

--- NEW FILE linux-2.6.15-cell-bogus-console-fix.patch ---
--- a/drivers/char/bogus_console.c~	2005-11-15 23:48:15.000000000 +0000
+++ a/drivers/char/bogus_console.c	2005-11-22 10:10:31.000000000 +0000
@@ -98,6 +98,7 @@ bog_tty_open (struct tty_struct *tty, st
 
 	tty->driver_data = &bog_tty_data;
 	bog_tty_data.buf_count = 0;
+	bog_tty_data.buf[BOG_TTY_BUF_SIZE] = 0;
 	bog_tty_data.tty = tty;
 	tty->low_latency = 0;
 	bog_tty_data.buf[0]=0;
@@ -113,49 +114,45 @@ bog_tty_close (struct tty_struct *tty, s
 }
 
 static int
-bog_tty_write (struct tty_struct *tty, const unsigned char *buf, int count)
-{
-	return 0;
-}
-
-static int
 bog_tty_write_room (struct tty_struct *tty)
 {
-	return BOG_TTY_BUF_SIZE;
+	return BOG_TTY_BUF_SIZE-1;
 }
 
 static void
 bog_tty_put_char (struct tty_struct *tty, unsigned char ch)
 {
-	char buff[BOG_TTY_BUF_SIZE];
-	int i;
+	BUG_ON(bog_tty_data.buf_count >= BOG_TTY_BUF_SIZE);
 
-	if (bog_tty_data.buf_count >= BOG_TTY_BUF_SIZE) {
-		for (i=0;i<bog_tty_data.buf_count+1;i++)
-			buff[i]=0;
-		strncpy(buff,bog_tty_data.buf,bog_tty_data.buf_count);
-		WriteConsole(buff);
-		bog_tty_data.buf_count = 0;
+	if (bog_tty_data.buf_count == BOG_TTY_BUF_SIZE-1) {
+		WriteConsole(bog_tty_data.buf);
+		bog_tty_data.buf_count = 0;
 	}
 	bog_tty_data.buf[bog_tty_data.buf_count] = ch;
 	bog_tty_data.buf_count++;
-	bog_tty_data.buf[bog_tty_data.buf_count] = 0;
 }
 
 static void
 bog_tty_flush_chars (struct tty_struct *tty)
 {
-	int i;
-	char buff[BOG_TTY_BUF_SIZE];
+	BUG_ON(bog_tty_data.buf_count >= BOG_TTY_BUF_SIZE);
 
-	for (i=0;i<bog_tty_data.buf_count+1;i++)
-		buff[i]=0;
-	strncpy(buff,bog_tty_data.buf,bog_tty_data.buf_count);
-	WriteConsole(buff);
+	bog_tty_data.buf[bog_tty_data.buf_count] = 0;
+	WriteConsole(bog_tty_data.buf);
 	bog_tty_data.buf_count = 0;
 }
 
 static int
+bog_tty_write (struct tty_struct *tty, const unsigned char *buf, int count)
+{
+	int i;
+	for (i=0; i<count; i++)
+		bog_tty_put_char(tty, buf[i]);
+	bog_tty_flush_chars(tty);
+	return count;
+}
+
+static int
 bog_tty_chars_in_buffer (struct tty_struct *tty)
 {
 	return 0;

linux-2.6.15-default-powerpc.patch:
 Makefile |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6.15-default-powerpc.patch ---
--- linux-2.6.14/Makefile.orig	2005-11-19 17:13:52.000000000 +0000
+++ linux-2.6.14/Makefile	2005-11-19 17:14:04.000000000 +0000
@@ -169,7 +169,7 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$
 SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
 				  -e s/arm.*/arm/ -e s/sa110/arm/ \
 				  -e s/s390x/s390/ -e s/parisc64/parisc/ \
-				  -e s/ppc64/powerpc/ )
+				  -e s/ppc.*/powerpc/ )
 
 # Cross compiling and selecting different set of gcc/bin-utils
 # ---------------------------------------------------------------------------

linux-2.6.15-mv643xx-fixes.patch:
 mv643xx_eth.c |  209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 204 insertions(+), 5 deletions(-)

--- NEW FILE linux-2.6.15-mv643xx-fixes.patch ---
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -78,6 +78,7 @@
 static int eth_port_link_is_up(unsigned int eth_port_num);
 static void eth_port_uc_addr_get(struct net_device *dev,
 						unsigned char *MacAddr);
+static void eth_port_set_multicast_list(struct net_device *);
 static int mv643xx_eth_real_open(struct net_device *);
 static int mv643xx_eth_real_stop(struct net_device *);
 static int mv643xx_eth_change_mtu(struct net_device *, int);
@@ -175,12 +176,17 @@ static void mv643xx_eth_rx_task(void *da
 		panic("%s: Error in test_set_bit / clear_bit", dev->name);
 
 	while (mp->rx_ring_skbs < (mp->rx_ring_size - 5)) {
-		skb = dev_alloc_skb(RX_SKB_SIZE);
+		skb = dev_alloc_skb(RX_SKB_SIZE+4);
 		if (!skb)
 			break;
 		mp->rx_ring_skbs++;
 		pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT;
 		pkt_info.byte_cnt = RX_SKB_SIZE;
+
+		/* Must have 8-byte alignment */
+		if ((unsigned long)skb->data & 4)
+			skb_reserve(skb, 4);
+
 		pkt_info.buf_ptr = dma_map_single(NULL, skb->data, RX_SKB_SIZE,
 							DMA_FROM_DEVICE);
 		pkt_info.return_info = skb;
@@ -267,6 +273,8 @@ static void mv643xx_eth_set_rx_mode(stru
 		mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
 
 	mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config);
+
+	eth_port_set_multicast_list(dev);
 }
 
 /*
@@ -2053,6 +2061,197 @@ static int eth_port_uc_addr(unsigned int
 	return 1;
 }
 
+static void eth_port_set_filter_table_entry(int table, unsigned char entry)
+{
+	unsigned int table_reg;
+	unsigned int tbl_offset;
+	unsigned int reg_offset;
+
+	tbl_offset = (entry / 4) * 4;	/* Register offset of DA table entry */
+	reg_offset = entry % 4;		/* Entry offset within the register */
+
+	/* Set "accepts frame bit" at specified table entry */
+	table_reg = mv_read(table + tbl_offset);
+	table_reg |= 0x01 << (8 * reg_offset);
+	mv_write(table + tbl_offset, table_reg);
+}
+
+/*******************************************************************************
+* eth_port_mc_addr - Multicast address settings.
+*
+* DESCRIPTION:
+*	This function controls the MV device MAC multicast support.
+*	The MV device supports multicast using two tables:
+*	1) Special Multicast Table for MAC addresses of the form
+*	   0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_FF).
+*	   The MAC DA[7:0] bits are used as a pointer to the Special Multicast
+*	   Table entries in the DA-Filter table.
+*	2) Other Multicast Table for multicast of another type. A CRC-8bit
+*	   is used as an index to the Other Multicast Table entries in the
+*	   DA-Filter table.  This function calculates the CRC-8bit value.
+*	In either case, eth_port_set_filter_table_entry() is then called
+*	to set to set the actual table entry.
+* INPUT:
+*	unsigned int 	eth_port_num	Port number.
+*	unsigned char 	*p_addr		Unicast MAC Address.
+*
+* OUTPUT:
+*	See description.
+*
+* RETURN:
+*	None.
+*
+*******************************************************************************/
+static void eth_port_mc_addr(unsigned int eth_port_num, unsigned char *p_addr)
+{
+	unsigned int mac_h;
+	unsigned int mac_l;
+	unsigned char crc_result = 0;
+	int table;
+	int mac_array[48];
+	int crc[8];
+	int i;
+
+	if ((p_addr[0] == 0x01) && (p_addr[1] == 0x00) &&
+	    (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
+		table = MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+					(eth_port_num);
+		eth_port_set_filter_table_entry(table, p_addr[5]);
+		return;
+	}
+
+	/* Calculate CRC-8 out of the given address */
+	mac_h = (p_addr[0] << 8) | (p_addr[1]);
+	mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
+			(p_addr[4] << 8) | (p_addr[5] << 0);
+
+	for (i = 0; i < 32; i++)
+		mac_array[i] = (mac_l >> i) & 0x1;
+	for (i = 32; i < 48; i++)
+		mac_array[i] = (mac_h >> (i - 32)) & 0x1;
+
+	crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ mac_array[39] ^
+		 mac_array[35] ^ mac_array[34] ^ mac_array[31] ^ mac_array[30] ^
+		 mac_array[28] ^ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
+		 mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ mac_array[12] ^
+		 mac_array[8]  ^ mac_array[7]  ^ mac_array[6]  ^ mac_array[0];
+
+	crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
+		 mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ mac_array[34] ^
+		 mac_array[32] ^ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
+		 mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ mac_array[21] ^
+		 mac_array[20] ^ mac_array[18] ^ mac_array[17] ^ mac_array[16] ^
+		 mac_array[15] ^ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
+		 mac_array[9]  ^ mac_array[6]  ^ mac_array[1]  ^ mac_array[0];
+
+	crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^ mac_array[43] ^
+		 mac_array[42] ^ mac_array[39] ^ mac_array[37] ^ mac_array[34] ^
+		 mac_array[33] ^ mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
+		 mac_array[24] ^ mac_array[22] ^ mac_array[17] ^ mac_array[15] ^
+		 mac_array[13] ^ mac_array[12] ^ mac_array[10] ^ mac_array[8]  ^
+		 mac_array[6]  ^ mac_array[2]  ^ mac_array[1]  ^ mac_array[0];
+
+	crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
+		 mac_array[40] ^ mac_array[38] ^ mac_array[35] ^ mac_array[34] ^
+		 mac_array[30] ^ mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
+		 mac_array[23] ^ mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
+		 mac_array[13] ^ mac_array[11] ^ mac_array[9]  ^ mac_array[7]  ^
+		 mac_array[3]  ^ mac_array[2]  ^ mac_array[1];
+
+	crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[41] ^
+		 mac_array[39] ^ mac_array[36] ^ mac_array[35] ^ mac_array[31] ^
+		 mac_array[30] ^ mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
+		 mac_array[19] ^ mac_array[17] ^ mac_array[15] ^ mac_array[14] ^
+		 mac_array[12] ^ mac_array[10] ^ mac_array[8]  ^ mac_array[4]  ^
+		 mac_array[3]  ^ mac_array[2];
+
+	crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^ mac_array[42] ^
+		 mac_array[40] ^ mac_array[37] ^ mac_array[36] ^ mac_array[32] ^
+		 mac_array[31] ^ mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
+		 mac_array[20] ^ mac_array[18] ^ mac_array[16] ^ mac_array[15] ^
+		 mac_array[13] ^ mac_array[11] ^ mac_array[9]  ^ mac_array[5]  ^
+		 mac_array[4]  ^ mac_array[3];
+
+	crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^ mac_array[41] ^
+		 mac_array[38] ^ mac_array[37] ^ mac_array[33] ^ mac_array[32] ^
+		 mac_array[29] ^ mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
+		 mac_array[19] ^ mac_array[17] ^ mac_array[16] ^ mac_array[14] ^
+		 mac_array[12] ^ mac_array[10] ^ mac_array[6]  ^ mac_array[5]  ^
+		 mac_array[4];
+
+	crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^ mac_array[39] ^
+		 mac_array[38] ^ mac_array[34] ^ mac_array[33] ^ mac_array[30] ^
+		 mac_array[29] ^ mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
+		 mac_array[18] ^ mac_array[17] ^ mac_array[15] ^ mac_array[13] ^
+		 mac_array[11] ^ mac_array[7]  ^ mac_array[6]  ^ mac_array[5];
+
+	for (i = 0; i < 8; i++)
+		crc_result = crc_result | (crc[i] << i);
+
+	table = MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num);
+	eth_port_set_filter_table_entry(table, crc_result);
+}
+
+/** Set the entire multicast list base on dev->mc_list. **/
+static void eth_port_set_multicast_list(struct net_device *dev)
+{
+
+	struct dev_mc_list	*mc_list;
+	int			i;
+	int			table_index;
+	struct mv643xx_private	*mp = netdev_priv(dev);
+	unsigned int		eth_port_num = mp->port_num;
+
+	/** If the device is in promiscuous mode or in all multicast mode,
+	 ** we will fully populate both multicast tables with accept.
+	 ** This is guaranteed to yield a match on all multicast addresses...
+	 **/
+	if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) {
+		for (table_index = 0; table_index <= 0xFC; table_index += 4) {
+			 /** Set all entries in DA filter special multicast
+			  ** table (Ex_dFSMT)
+			  ** Set for ETH_Q0 for now
+			  ** Bits
+			  ** 0	  Accept=1, Drop=0
+			  ** 3-1  Queue	 ETH_Q0=0
+			  ** 7-4  Reserved = 0;
+			  **/
+			 mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+
+			 /** Set all entries in DA filter other multicast
+			  ** table (Ex_dFOMT)
+			  ** Set for ETH_Q0 for now
+			  ** Bits
+			  ** 0	  Accept=1, Drop=0
+			  ** 3-1  Queue	 ETH_Q0=0
+			  ** 7-4  Reserved = 0;
+			  **/
+			 mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+       	}
+		return;
+	}
+
+	/** We will clear out multicast tables everytime we get the list.
+	 ** Then add the entire new list...
+	 **/
+	for (table_index = 0; table_index <= 0xFC; table_index += 4) {
+		/* Clear DA filter special multicast table (Ex_dFSMT) */
+		mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+				(eth_port_num) + table_index, 0);
+
+		/* Clear DA filter other multicast table (Ex_dFOMT) */
+		mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
+				(eth_port_num) + table_index, 0);
+	}
+
+	/** Get pointer to net_device multicast list and add each one... **/
+	for(i = 0, mc_list = dev->mc_list;
+			(i < 256) && (mc_list != NULL) && (i < dev->mc_count);
+			i++, mc_list = mc_list->next)
+		if (mc_list->dmi_addrlen == 6)
+			eth_port_mc_addr(eth_port_num, mc_list->dmi_addr);
+}
+
 /*
  * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
  *
@@ -2080,11 +2279,11 @@ static void eth_port_init_mac_tables(uns
 
 	for (table_index = 0; table_index <= 0xFC; table_index += 4) {
 		/* Clear DA filter special multicast table (Ex_dFSMT) */
-		mv_write((MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
-					(eth_port_num) + table_index), 0);
+		mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+					(eth_port_num) + table_index, 0);
 		/* Clear DA filter other multicast table (Ex_dFOMT) */
-		mv_write((MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
-					(eth_port_num) + table_index), 0);
+		mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
+					(eth_port_num) + table_index, 0);
 	}
 }
 

linux-2.6.15-ppc-cell-basics.patch:
 arch/powerpc/Kconfig                                         |   14 
 arch/powerpc/kernel/entry_64.S                               |    4 
 arch/powerpc/kernel/head_64.S                                |   41 +
 arch/powerpc/kernel/prom_init.c                              |    2 
 arch/powerpc/platforms/cell/iommu.c                          |    6 
 arch/powerpc/platforms/cell/spider-pic.c                     |    4 
 drivers/block/Makefile                                       |    1 
 drivers/char/Kconfig                                         |    6 
 drivers/char/Makefile                                        |    1 
 include/asm-powerpc/processor.h                              |   17 
 linux-2.6.14-rc/drivers/char/bogus_console.c                 |  315 +++++++++
 linux-2.6.14/drivers/net/Makefile                            |    2 
 linux-2.6.14/drivers/net/mambonet.c                          |  362 +++++++++++
 linux-2.6.15-rc/drivers/block/mambo_bd.c                     |  252 +++++++
 linux-2.6.15-rc/include/asm-powerpc/mambo/callthru_config.h  |  241 +++++++
 linux-2.6.15-rc/include/asm-powerpc/mambo/sim_support_code.h |  171 +++++
 linux-2.6.15-rc/include/linux/mambobd.h                      |   38 +
 17 files changed, 1475 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6.15-ppc-cell-basics.patch ---
unchanged:
--- linux-2.6.15-rc.orig/arch/powerpc/platforms/cell/iommu.c
+++ linux-2.6.15-rc/arch/powerpc/platforms/cell/iommu.c
@@ -374,7 +374,11 @@ static int cell_dma_supported(struct dev
 
 void cell_init_iommu(void)
 {
-	cell_map_iommu();
+	if (__onsim()) {
+		printk(KERN_INFO "Not using iommu on mambo\n");
+	} else {
+		cell_map_iommu();
+	}
 
 	/* Direct I/O, IOMMU off */
 	ppc_md.iommu_dev_setup = iommu_dev_setup_null;
unchanged:
--- linux-2.6.15-rc.orig/arch/powerpc/kernel/entry_64.S
+++ linux-2.6.15-rc/arch/powerpc/kernel/entry_64.S
@@ -35,6 +35,10 @@
 #define DO_SOFT_DISABLE
 #endif
 
+_GLOBAL(callthru)
+        .long 0x7c0007cc
+        blr
+
 /*
  * System calls.
  */
unchanged:
--- linux-2.6.15-rc.orig/include/asm-powerpc/processor.h
+++ linux-2.6.15-rc/include/asm-powerpc/processor.h
@@ -284,6 +284,23 @@ static inline void pause_zero(void)
 }
 #endif
 
+#ifdef CONFIG_PPC_CELL /* MAMBO SIMULATION code */
+#define MSR_SIM_LG      29
+#define MSR_SIM         __MASK(MSR_SIM_LG)
+
+static __inline__ int __onsim(void)
+{
+        unsigned long msr;
+        __asm__ __volatile__ ("mfmsr    %0" : "=&r" (msr));
+        return ((msr & MSR_SIM) ? 1 : 0);
+}
+#endif /* CONFIG_PPC_CELL */
+
 #endif /* __KERNEL__ */
+#else
+/* must be given a register to perform the compare, set cr0 = 1
+ * Usage: __onsim(r0); bne _if_onsim
+ */
+#define __onsim(r) mfmsr        r; rldicl. r,r,35,63
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_POWERPC_PROCESSOR_H */
unchanged:
--- /dev/null
+++ linux-2.6.15-rc/include/asm-powerpc/mambo/callthru_config.h
@@ -0,0 +1,241 @@
+/*********************************************************
+ *
+ * (C) Copyright IBM Corporation 2001, 2003
+ *
+ * Filename : callthru_config.h
+ *
+ * Originator   : Patrick Bohrer
+ *
+ * Purpose  :
+ *
+ *   This file is compiled with programs that are run under the Mambo
+ *   simulator.  For example, stand-alone programs or operating
+ *   systems.  (This file is not compiled info Mambo!)  The programs
+ *   call the callthru wrapper functions which use an illegal PowerPC
+ *   instruction to signal the Mambo simulator to emulate special
+ *   support.
+ *
+ *********************************************************/
+
+#ifndef _CALLTHRU_CONFIG_H_
+#define _CALLTHRU_CONFIG_H_
+
+#include "sim_support_code.h"
+
+#define CAST(t,e) ((t)(e))
+
+/* The AIX xlc compiler does not seem to like the gcc
+   "static inline" declaration. */
+#ifdef __GNUC__
+#define INLINE static inline
+#else /* #ifdef __GNUC__ */
+#define INLINE static
+#endif /* #ifdef __GNUC__ */
+
+
+/* The functions callthru0 to callthru5 setup up the arguments for the
+ * Mambo callthru and then use the callthru instruction.  Note that
+ * 0-5 specify the number of arguments after the command */
+
+/* Note: Arguments are cast as unsigned long to prevent casting by the
+   compiler.  This way, you can pass pointers, integers, etc. in
+   machine register and have the Mambo simulator interpret what the
+   register is supposed to be.  To help with typing errors when using
+   callthrus, we provide wrapper functions for each callthru.  The
+   wrappers cast all arguments to unsigned long.  Unfortunately, this results
+   in a lot of compiler warnings that I do not know how to remove.  If
+   you modify this code, be aware that we are trying to pick a type
+   that is the size of the registers (32-bit or 64-bit) and that is
+   why are choosing to cast to a void* (it should be the size of a
+   machine register) */
+
+INLINE int callthru0(int command)
+{
+    register int c asm ("r3") = command;
+    asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c));
+    return((c));
+}
+INLINE int callthru1(int command, unsigned long arg1)
+{
+    register int c asm ("r3") = command;
+    register unsigned long a1 asm ("r4") = arg1;
+    asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1));
+    return((c));
+}
+INLINE int callthru2(int command, unsigned long arg1, unsigned long arg2)
+{
+    register int c asm ("r3") = command;
+    register unsigned long a1 asm ("r4") = arg1;
+    register unsigned long a2 asm ("r5") = arg2;
+    asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1), "r" (a2));
+    return((c));
+}
+INLINE int callthru3(int command, unsigned long arg1, unsigned long arg2, unsigned long arg3)
+{
+    register int c asm ("r3") = command;
+    register unsigned long a1 asm ("r4") = arg1;
+    register unsigned long a2 asm ("r5") = arg2;
+    register unsigned long a3 asm ("r6") = arg3;
+    asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1), "r" (a2), "r" (a3));
+    return((c));
+}
+INLINE int callthru4(int command, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4)
+{
+    register int c asm ("r3") = command;
+    register unsigned long a1 asm ("r4") = arg1;
+    register unsigned long a2 asm ("r5") = arg2;
+    register unsigned long a3 asm ("r6") = arg3;
+    register unsigned long a4 asm ("r7") = arg4;
+    asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1), "r" (a2), "r" (a3), "r" (a4));
+    return((c));
+}
+INLINE int callthru5(int command, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
+{
+    register int c asm ("r3") = command;
+    register unsigned long a1 asm ("r4") = arg1;
+    register unsigned long a2 asm ("r5") = arg2;
+    register unsigned long a3 asm ("r6") = arg3;
+    register unsigned long a4 asm ("r7") = arg4;
+    register unsigned long a5 asm ("r8") = arg5;
+    asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5));
+    return((c));
+}
+INLINE int callthru6(int command, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
+{
+    register int c asm ("r3") = command;
+    register unsigned long a1 asm ("r4") = arg1;
+    register unsigned long a2 asm ("r5") = arg2;
+    register unsigned long a3 asm ("r6") = arg3;
+    register unsigned long a4 asm ("r7") = arg4;
+    register unsigned long a5 asm ("r8") = arg5;
+    register unsigned long a6 asm ("r9") = arg6;
+    asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6));
+    return((c));
+}
+INLINE int callthru7(int command, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7)
+{
+    register int c asm ("r3") = command;
+    register unsigned long a1 asm ("r4") = arg1;
+    register unsigned long a2 asm ("r5") = arg2;
+    register unsigned long a3 asm ("r6") = arg3;
+    register unsigned long a4 asm ("r7") = arg4;
+    register unsigned long a5 asm ("r8") = arg5;
+    register unsigned long a6 asm ("r9") = arg6;
+    register unsigned long a7 asm ("r10") = arg7;
+    asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7));
+    return((c));
+}
+
+
+
+/* Wrappers for simulator callthrus */
+
+INLINE int MamboWriteConsole( char *string )
+{
+    return(callthru3( SimWriteConsoleCode, CAST(unsigned long,string), CAST(unsigned long,strlen(string)), CAST(unsigned long,1) ));
+}
+
+INLINE int MamboStopSimulation(void)
+{
+    return(callthru0( SimExitCode));
+}
+
+INLINE int MamboReadConsole(void)
+{
+    return(callthru0( SimReadConsoleCode));
+}
+
+INLINE int MamboThinIPRead( char *string, int length )
+{
+    return(callthru2( SimThinIPReadCode, CAST(unsigned long,string), CAST(unsigned long,length)));
+}
+
+INLINE int MamboThinIPWrite( char *string, int length )
+{
+    return(callthru2( SimThinIPWriteCode, CAST(unsigned long,string), CAST(unsigned long,length)));
+}
+
+INLINE int MamboGetConfig( CallthruConfig *config )
+{
+    return(callthru1( SimGetConfigCode, CAST(unsigned long,config)));
+}
+
+INLINE int MamboLogStats( char *comment, int id )
+{
+    return(callthru2( SimLogStatsCode, CAST(unsigned long,comment), CAST(unsigned long,id)));
+}
+
+INLINE int MamboPPCOnly( int newstate )
+{
+    return(callthru1( SimPPCOnlyCode, CAST(unsigned long,newstate)));
+}
+
+INLINE int MamboPIDCreate(int parent, int pid, int flags)
+{
+    return(callthru3(SimPIDCreateCode,CAST(unsigned long,parent),CAST(unsigned long,pid),CAST(unsigned long,flags)));
+}
+
+INLINE int MamboPIDExecExit(int pid)
+{
+    return(callthru1(SimPIDExecExitCode, CAST(unsigned long,pid)));
+}
+
+INLINE int MamboPIDExec(int pid, char *filename, int len)
+{
+    return(callthru3(SimPIDExecCode, CAST(unsigned long,pid), CAST(unsigned long,filename), CAST(unsigned long,len)));
+}
+
+INLINE int MamboPIDResume(int processor, int pid)
+{
+    return(callthru3(SimPIDResumeCode, CAST(unsigned long,processor), CAST(unsigned long,pid), CAST(unsigned long,0)));
+}
+
+INLINE int MamboPIDKill(int pid)
+{
+    return(callthru1(SimPIDKillCode,CAST(unsigned long,pid)));
+}
+INLINE int MamboKernelThreadCreate(int parent, int pid, int flags)
+{
+    return(callthru3(SimKernelThreadCreateCode,CAST(unsigned long,parent),CAST(unsigned long,pid),CAST(unsigned long,flags)));
+}
+
+INLINE int MamboBogusDiskRead( int devno, void *buf, ulong sect, ulong nrsect)
+{
+    return callthru3( SimBogusDiskReadCode, CAST(unsigned long,buf), CAST(unsigned long,sect),
+                      CAST(unsigned long,(nrsect<<16)|devno));
+}
+
+INLINE int MamboBogusDiskWrite( int devno, void *buf, ulong sect, ulong nrsect)
+{
+    return callthru3( SimBogusDiskWriteCode, CAST(unsigned long,buf), CAST(unsigned long,sect),
+                      CAST(unsigned long,(nrsect<<16)|devno));
+}
+INLINE int MamboBogusDiskInfo( int op, int devno)
+{
+    return(callthru2( SimBogusDiskInfoCode, CAST(unsigned long,op), CAST(unsigned long,devno)));
+}
+
+INLINE int MamboBogusNetProbe( int devno, void *buf)
+{
+    return(callthru2( SimBogusNetProbeCode, CAST(unsigned long,devno), CAST(unsigned long,buf) ));
+}
+
+INLINE int MamboBogusNetSend( int devno, void *buf, ulong size)
+{
+    return(callthru3( SimBogusNetSendCode, CAST(unsigned long,devno), CAST(unsigned long,buf), CAST(unsigned long,size)));
+}
+
+INLINE int MamboBogusNetRecv( int devno, void *buf, ulong size)
+{
+    return(callthru3( SimBogusNetRecvCode, CAST(unsigned long,devno), CAST(unsigned long,buf), CAST(unsigned long,size)));
+}
+
+INLINE void BogusHalt( void ) { callthru0( SimBogusHaltCode ); }
+
+INLINE int MamboKernelMmapFile(char *buffer, int pathlen, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flag, unsigned long offset)
+{
+    return(callthru7( SimKernelMmapFileCode, CAST(unsigned long,buffer), CAST(unsigned long,pathlen), CAST(unsigned long,addr), CAST(unsigned long,len), CAST(unsigned long,prot), CAST(unsigned long,flag), CAST(unsigned long,offset)));
+}
+
+#endif /* #ifndef _CALLTHRU_CONFIG_H_ */
+
unchanged:
--- /dev/null
+++ linux-2.6.15-rc/include/asm-powerpc/mambo/sim_support_code.h
@@ -0,0 +1,171 @@
+/*********************************************************
+ *
+ * (C) Copyright IBM Corporation 2001, 2003
+ *
+ * Filename : sim_support_code.h
+ *
+ * Originator : Charles Lefurgy
+ *
+ * Purpose : This file is shared between Mambo and OSes (Linux, K42).
+ *
+ *********************************************************/
+
+#ifndef _SIM_SUPPORT_CODE_H_
+#define _SIM_SUPPORT_CODE_H_
+
+
+typedef struct CallthruCacheConfig
+{
+    int dcache_size;                /* bytes */
+    int dcache_assoc;
+    int dcache_line_size;           /* bytes */
+    int dcache_block_size;          /* bytes */
+
+    int icache_size;                /* bytes */
+    int icache_assoc;
+    int icache_line_size;           /* bytes */
+    int icache_block_size;          /* bytes */
+
+    int l2cache_size;               /* bytes */
+    int l2cache_assoc;
+    int l2cache_line_size;          /* bytes */
+} CallthruCacheConfig;
+
+typedef struct CallthruConfig
+{
+    int         num_cpus;
+    int         cpu_clock_freq;     /* Mhz */
+    unsigned long long      mem_size;       /* bytes */
+    CallthruCacheConfig cache;
+} CallthruConfig;
+
+
+
+/*
+ * Support functions that can be invoked by the simulated program
+ *
+ * Simulated reg 3 contains code indicating which function to perform: */
+typedef enum
+{
+    SimWriteConsoleCode = 0,         /*  0 */
+    SimDiskReadCode,                 /*  1 */
+    SimDiskWriteCode,                /*  2 */
+    SimDeviceIntRegisterCode,        /*  3 */
+    SimDeviceIntDeregisterCode,      /*  4 */
+    SimDeviceEnableIntCode,          /*  5 */
+    SimDeviceDisableIntCode,         /*  6 */
+    SimGetIntStreamForDeviceCode,    /*  7 */
+    SimResetIntForStreamCode,        /*  8 */
+    SimCharReadCode,                 /*  9 */
+    SimCharWriteCode,                /* 10 */
+    SimGetInterruptingLevelCode,     /* 11 */
+    SimSetExternalLevelMaskCode,     /* 12 */
+    SimSetInterruptCode,             /* 13 */
+    SimMapLevelCode,                 /* 14 */
+    SimResetInterruptCode,           /* 15 */
+    SimFileOpenCode,                 /* 16 */
+    SimFileCloseCode,                /* 17 */
+    SimFileReadCode,                 /* 18 */
+    SimFileWriteCode,                /* 19 */
+    SimTakeCheckpointCode,           /* 20 */
+    SimInterruptEOICode,             /* 21 */
+    SimShellCode,                    /* 22 */
+    SimBlockIOCode,                  /* 23 */
+    SimGetCookieCode,                /* 24 */
+    SimDumpStatsCode,                /* 25 */
+    SimReturnStatsCode = 30,         /* 30 */
+    SimExitCode,                     /* 31 */
+    SimDumpPPCStatsCode = 32,        /* 32 */ /* used in cyclesim + ??? */
+    SimClearPPCStatsCode = 33,       /* 33 */ /* used in cyclesim + ??? */
+    SimCopyQuickCode = 34,           /* 34 */ /* shortcut a long memory copy */
+    /* 35 */ /* bmark under test for power validation in cyclesim */
+    SimSetTestNameCode = 35,
+
+    SimDumpSystemStatsCode = 36,           /* 36 */
+    SimClearSystemStatsCode = 37,          /* 37 */
+    SimSystemMemTraceEnableCode = 38,      /* 38 */
+    SimSystemMemTraceDisableCode = 39,     /* 39 */
+
+    SimTCLReadCode = 40,              /* 40 */
+    SimTCLWriteCode,                  /* 41 */
+    SimFileLoadedByAIXCode = 50,        /* 50 */
+    SimUnloadedFileCode,              /* 51 */
+    SimDumpStateCode,                 /* 52 */ /* get a machine attribute */
+
+    SimReadConsoleCode = 60,          /* 60 */ /* k42 codes starting at 60 */
+    SimThinIPReadCode,                /* 61 */ /* thinIP read */
+    SimThinIPWriteCode,               /* 62 */ /* thinIP write */
+    SimFastRevMemCopyCode,            /* 63 */ /* fast rev mem cpy */
+    SimStartCPUCode,                  /* 64 */ /* start a cpu */
+    SimSendIPICode,                   /* 65 */ /* make an IPI */
+    SimGetInstrCountCode,             /* 66 */ /* get instr count */
+    SimGetNumbPhysProcsCode,          /* 67 */ /* get numb procs */
+    SimGetMachAttrCode,               /* 68 */ /* get a machine attribute */
+    SimPhysMemCopyCode,               /* 69 */ /* a fast phys to phys mem copy */
+    SimGetTimeCode,                   /* 70 */ /* get a time */
+    SimPhysMemSetCode,                /* 71 */ /* a fast memory set routine */
+    SimTraceFileCtlCode,              /* 72 */ /* allows open, write, close */
+
+    /* 80 */ /* read up to 4096 bytes from a simulator disk */
+    SimDiskReadK42Code = 80,
+
+    /* 81 */ /* write up to 4096 bytes to a simulator disk */
+    SimDiskWriteK42Code,
+
+    /* 82 */ /* open simulator disk; return disk size */
+    SimDiskOpenK42Code,
+
+    /* 83 */ /* close simulator disk; NOT YET IMPLEMENTED */
+    SimDiskCloseK42Code,
+
+
+    SimGetConfigCode,          /* 84 */ /* read the system configuration */
+    /* 85 */ /* print out the stats with a comment and id */
+    SimLogStatsCode,
+
+
+    /* 86 */ /* execute the passed string as a tcl procedure */
+    SimCallTCLCode,
+
+    SimPROMCode = 99,              /* 99 */ /* Handle open firmware calls */
+
+#if 1 // def STI
+    SimPPCOnlyCode = 100,             /* 100 */ /* Turn PPC-ONLY mode on or off */
+#endif /* #ifdef STI */
+/* mco hooks to linux kernel process creation destruction routines */
+    SimPIDCreateCode = 101,         /* 101 */ /* fork a proc */
+    SimPIDExecExitCode,             /* 102 */ /* exit() */
+    SimPIDExecCode,                 /* 103 */ /* execve() */
+    SimPIDResumeCode,               /* 104 */ /* */
+    SimPIDKillCode,                 /* 105 */ /* */
+    SimKernelThreadCreateCode,      /* 106 */ /* kernel_thread() */
+    SimKernelStartedCode,           /* 107 */ /* kernel finished booting */
+    SimLinuxLoadShlibCode,          /* 108 */ /* linux load_elf_library() */
+    SimOpenConnectionCode = 110,    /* 110 */ /* open connection code */
+    SimCloseConnectionCode,         /* 111 */ /* close connection code */
+    SimReadConnectionCode,          /* 112 */ /* read connection code */
+    SimWriteConnectionCode,         /* 113 */ /* write connection code */
+    SimSelectConnectionCode,        /* 114 */ /* select connection code */
+    SimPthreadCreateCode,           /* 115 traps into simulator to create/start a pthread */
+
+    SimBogusDiskReadCode,           /* 116 mambo bogus disk block read */
+    SimBogusDiskWriteCode,          /* 117 mambo bogus disk block write */
+    SimBogusDiskInfoCode,           /* 118 mambo bogus disk info op */
+    SimBogusNetProbeCode,           /* 119 mambo bogus net probe op */
+    SimBogusNetSendCode,            /* 120 mambo bogus net send op */
+    SimBogusNetRecvCode,            /* 121 mambo bogus net recv op */
+
+    SimFileLoadedByOSCode,          /* 122 */
+
+    SimKernelThreadCallCode,        /* 123 */ /* kernel_thread() */
+
+    SimKernelMmapFileCode,          /* 124 */ /* do_mmap from linux */
+
+    SimDumpMemoryCode,              /* 125 */ /* print memory region to file */
+    SimBogusHaltCode,               /* 126 */ /* bogus halt for idle */
+
+
+    SimLastCode /* This must be last in this list */
+} SimSupportCode;
+
+#endif /* #ifndef _SIM_SUPPORT_CODE_H_ */
unchanged:
--- linux-2.6.15-rc/arch/powerpc/Kconfig
+++ linux-2.6.14/arch/powerpc/Kconfig	2005-11-16 01:31:12.000000000 +0000
@@ -421,6 +421,20 @@
 	  some command-line options at build time by entering them here.  In
 	  most cases you will need to specify the root device here.
 
+config MAMBO_BD
+	bool "Mambo Block driver stuff"
+	depends on PPC_PSERIES || PPC_CELL
+	---help---
+	mambo block device driver
+
+config MAMBO_NET
+        depends on PPC_PSERIES || PPC_CELL
+        tristate "    IBM Full System Simulator Bogus Network Support"
+        default y
+        ---help---
+           Provides quick access to a raw ethernet device in the simulator
+           without simulating any specific network device hardware.
+
 endmenu
 
 config ISA_DMA_API
unchanged:
--- linux-2.6.15-rc.orig/arch/powerpc/kernel/head_64.S
+++ linux-2.6.15-rc/arch/powerpc/kernel/head_64.S
@@ -36,6 +36,7 @@
 #include <asm/hvcall.h>
 #include <asm/iseries/lpar_map.h>
 #include <asm/thread_info.h>
+#include <asm/processor.h>
 
 #ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
@@ -1606,6 +1606,10 @@ _STATIC(__after_prom_start)
  * Note: this routine *only* clobbers r0, r6 and lr
  */
 _GLOBAL(copy_and_flush)
+#ifdef CONFIG_PPC_CELL
+	__onsim(r0)
+	bne     _sim_copy_and_flush
+#endif
 	addi	r5,r5,-8
 	addi	r6,r6,-8
 4:	li	r0,16			/* Use the least common		*/
@@ -1632,6 +1636,42 @@ _GLOBAL(copy_and_flush)
 	addi	r6,r6,8
 	blr
 
+#ifdef CONFIG_PPC_CELL
+_sim_copy_and_flush:
+/*
+ * Use Simulators copy cut-thru
+ * which is SimOSSupport(SimPhysMemCopyK, dst, src, size);
+ */
+	mr      r0,r6
+	mr      r6,r5
+	subf    r6,r0,r6
+
+	mr      r5,r4
+	add     r5,r5,r0
+
+	mr      r4,r3
+	add     r4,r4,r0
+
+	li      r3,69           # SimPhysMemCopyK
+	.long 0x000EAEB0        # SimOS trap
+
+	## restore
+	mr      r3,r4
+	subf    r3,r0,r3
+
+	mr      r4,r5
+	subf    r4,r0,r4
+
+	mr      r5,r6
+	add     r5,r5,r0
+
+	## r6 needs to be r5 rounded up to nearest 8
+	mr      r6,r5
+	addi    r6,r6,7
+	rldicr  r6,r6,0,60
+	blr
+#endif
+
 .align 8
 copy_to_here:
 
unchanged:
--- linux-2.6.15-rc.orig/arch/powerpc/platforms/cell/spider-pic.c
+++ linux-2.6.15-rc/arch/powerpc/platforms/cell/spider-pic.c
@@ -159,6 +159,10 @@ void spider_init_IRQ(void)
 	long pics[] = { 0x24000008000, 0x34000008000 };
 	int n;
 
+	if (__onsim()) {
+		return;
+	}
+
 /* FIXME: detect multiple PICs as soon as the device tree has them */
 	for (node = 0; node < num_present_cpus()/2; node++) {
 #if 0
unchanged:
--- linux-2.6.15-rc.orig/drivers/block/Makefile
+++ linux-2.6.15-rc/drivers/block/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_CDROM_PKTCDVD)	+= pktcdvd.o
 
 obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_NBD)	+= nbd.o
+obj-$(CONFIG_MAMBO_BD)		+= mambo_bd.o
 obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
 
 obj-$(CONFIG_VIODASD)		+= viodasd.o
unchanged:
--- /dev/null
+++ linux-2.6.15-rc/drivers/block/mambo_bd.c
@@ -0,0 +1,252 @@
+/*
+ * Mambo Block Driver - expose block devices through mambo callthru
+ *
+ * copyright 2003 IBM
+ *
+ */
+
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/ioctl.h>
+#include <net/sock.h>
+
+#include <asm/mambo/callthru_config.h>
+
+#include <linux/devfs_fs_kernel.h>
+
+#include <asm/uaccess.h>
+#include <asm/types.h>
+
+#define MAJOR_NR 42
+#include <linux/mambobd.h>
+
+static struct mbd_device mbd_dev[MAX_MBD];
+
+#define BD_INFO_SYNC   0
+#define BD_INFO_STATUS 1
+#define BD_INFO_BLKSZ  2
+#define BD_INFO_DEVSZ  3
+#define BD_INFO_CHANGE 4
+
+static int
+mbd_init_disk (int devno)
+{
+  /* check disk configured */
+  if (!MamboBogusDiskInfo (BD_INFO_STATUS, devno))
+    {
+      printk (KERN_ERR
+	      "Attempting to open bogus disk before initializaiton\n");
+      return 0;
+    }
+
+  mbd_dev[devno].initialized++;
+#ifdef DEBUG
+  printk ("<1>Bogus Device %d Init\n", devno);
+#endif
+
+  return 1;
+}
+
+static void
+do_mbd_request (request_queue_t * q)
+{
+  int result = 0;
+  struct request *req;
+
+  while ((req = elv_next_request(q)) != NULL)
+    {
+      int minor = req->rq_disk->first_minor;
+
+#ifdef DEBUG
+      dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%lx)\n",
+      		req->rq_disk->disk_name, req, req->flags);
+#endif
+
+      switch (rq_data_dir (req))
+	{
+	case READ:
+	  result = MamboBogusDiskRead (minor,
+				       req->buffer, req->sector,
+				       req->current_nr_sectors);
+	  break;
+	case WRITE:
+	  result = MamboBogusDiskWrite (minor,
+					req->buffer, req->sector,
+					req->current_nr_sectors);
+	};
+
+      if (result)
+	end_request (req, 0);	/* failure */
+      else
+	end_request (req, 1);	/* success */
+    }
+}
+
+static int
+mbd_release (struct inode *inode, struct file *file)
+{
+  struct mbd_device *lo;
+  int dev;
+
+  if (!inode)
+    return -ENODEV;
+  dev = inode->i_bdev->bd_disk->first_minor;
+  if (dev >= MAX_MBD)
+    return -ENODEV;
+  if (MamboBogusDiskInfo (BD_INFO_SYNC, dev) < 0)
+    {
+      printk (KERN_ALERT "mbd_release: unable to sync\n");
+    }
+  lo = &mbd_dev[dev];
+  if (lo->refcnt <= 0)
+    printk (KERN_ALERT "mbd_release: refcount(%d) <= 0\n", lo->refcnt);
+  lo->refcnt--;
+  return 0;
+}
+
+#if 0
+static int
+mbd_check_change (struct gendisk *disk)
+{
+  int devno = disk->first_minor;
+
+  if (MamboBogusDiskInfo (BD_INFO_CHANGE, devno))
+    return 1;
+
+  return 0;
+}
+#endif
+
+static int
+mbd_revalidate (struct gendisk *disk)
+{
+  int devno = disk->first_minor;
+
+  mbd_init_disk (devno);
+
+  return 0;
+}
+
+static int
+mbd_open (struct inode *inode, struct file *file)
+{
+  int dev;
+
+  if (!inode)
+    return -EINVAL;
+  dev = inode->i_bdev->bd_disk->first_minor;
+  if (dev >= MAX_MBD)
+    return -ENODEV;
+
+  check_disk_change (inode->i_bdev);
+
+  if (!mbd_dev[dev].initialized)
+    if (!mbd_init_disk (dev))
+      return -ENODEV;
+
+  mbd_dev[dev].refcnt++;
+  return 0;
+}
+
+static struct block_device_operations mbd_fops = {
+owner:THIS_MODULE,
+open:mbd_open,
+release:mbd_release,
+  /* media_changed:      mbd_check_change, */
+revalidate_disk:mbd_revalidate,
+};
+
+static spinlock_t mbd_lock = SPIN_LOCK_UNLOCKED;
+
+static int __init
+mbd_init (void)
+{
+  int err;
+  int i;
+
+  if (!__onsim())
+	return 0;
+
+  err = -ENOMEM;
+  for (i = 0; i < MAX_MBD; i++)
+    {
+      struct gendisk *disk = alloc_disk (1);
+      if (!disk)
+	goto out;
+      mbd_dev[i].disk = disk;
+      /*
+       * The new linux 2.5 block layer implementation requires
+       * every gendisk to have its very own request_queue struct.
+       * These structs are big so we dynamically allocate them.
+       */
+      disk->queue = blk_init_queue (do_mbd_request, &mbd_lock);
+      if (!disk->queue)
+	{
+	  put_disk (disk);
+	  goto out;
+	}
+    }
+
+  if (register_blkdev (MAJOR_NR, "mbd"))
+    {
+      err = -EIO;
+      goto out;
+    }
+
+#ifdef MODULE
+  printk ("mambo bogus disk: registered device at major %d\n", MAJOR_NR);
+#else
+  printk ("mambo bogus disk: compiled in with kernel\n");
+#endif
+
+  devfs_mk_dir ("mambobd");
+  for (i = 0; i < MAX_MBD; i++)
+    {				/* load defaults */
+      struct gendisk *disk = mbd_dev[i].disk;
+      mbd_dev[i].initialized = 0;
+      mbd_dev[i].refcnt = 0;
+      mbd_dev[i].flags = 0;
+      disk->major = MAJOR_NR;
+      disk->first_minor = i;
+      disk->fops = &mbd_fops;
+      disk->private_data = &mbd_dev[i];
+      sprintf (disk->disk_name, "mambobd%d", i);
+      sprintf (disk->devfs_name, "mambobd%d", i);
+      set_capacity (disk, 0x3ffffe);
+      add_disk (disk);
+    }
+
+  return 0;
+out:
+  while (i--)
+    {
+      if (mbd_dev[i].disk->queue)
+	blk_cleanup_queue (mbd_dev[i].disk->queue);
+      put_disk (mbd_dev[i].disk);
+    }
+  return -EIO;
+}
+
+static void __exit
+mbd_cleanup (void)
+{
+  devfs_remove("mambobd");
+
+  if (unregister_blkdev (MAJOR_NR, "mbd") != 0)
+    printk ("mbd: cleanup_module failed\n");
+  else
+    printk ("mbd: module cleaned up.\n");
+}
+
+module_init (mbd_init);
+module_exit (mbd_cleanup);
+
+MODULE_DESCRIPTION ("Mambo Block Device");
+MODULE_LICENSE ("GPL");
unchanged:
--- /dev/null
+++ linux-2.6.15-rc/include/linux/mambobd.h
@@ -0,0 +1,38 @@
+/*
+ * 2001 Copyright (C) IBM
+ */
+
+#ifndef LINUX_MAMBOBD_H
+#define LINUX_MAMBOBD_H
+
+#ifdef MAJOR_NR
+
+#include <asm/semaphore.h>
+
+#ifdef _STIDC_LINUX_25
+#include <linux/blk.h>
+#else
+#include <linux/blkdev.h>
+#endif
+
+#ifdef PARANOIA
+extern int requests_in;
+extern int requests_out;
+#endif
+
+#define MAX_MBD 128
+
+#define MBD_SET_BLKSIZE _IO( 0xab, 1 )
+#define MBD_SET_SIZE    _IO( 0xab, 2 )
+#define MBD_SET_SIZE_BLOCKS     _IO( 0xab, 7 )
+#define MBD_DISCONNECT  _IO( 0xab, 8 )
+
+struct mbd_device {
+  int initialized;
+  int refcnt;
+  int flags;
+  struct gendisk * disk;
+};
+#endif
+
+#endif
unchanged:
--- linux-2.6.14/drivers/net/mambonet.c.orig	2005-11-16 01:29:06.000000000 +0000
+++ linux-2.6.14/drivers/net/mambonet.c	2005-11-16 00:53:28.000000000 +0000
@@ -0,0 +1,362 @@
+/*
+ * Mambonet Driver
+ *
+ * copyright 2003 IBM
+ * JimiX (jimix at watson.ibm.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/in.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <linux/if_ether.h>	/* For the statistics structure. */
+#include <linux/if_arp.h>	/* For ARPHRD_ETHER */
+#include <linux/workqueue.h>
+#include <asm/prom.h>
+#include <linux/version.h>
+#include <asm/mambo/callthru_config.h>
+
+static irqreturn_t 
+mambonet_interrupt(int irq, void *dev_instance,
+		   struct pt_regs * regs);
+
+#define INIT_BOTTOM_HALF(x,y,z) INIT_WORK(x, y, (void*)z)
+#define SCHEDULE_BOTTOM_HALF(x) schedule_delayed_work(x, 1)
+#define KILL_BOTTOM_HALF(x) cancel_delayed_work(x); flush_scheduled_work()
+
+#define MAMBO_MTU 1500
+
+struct netdev_private {
+	int             devno;
+	int             closing;
+	struct work_struct poll_task;
+	struct net_device_stats stats;
+};
+
+static int
+mambonet_probedev(int devno, void *buf)
+{
+	struct device_node *mambo;
+	struct device_node *net;
+	unsigned int   *reg;
+
+	mambo = find_path_device("/mambo");
+
+	if (mambo == NULL) {
+		return -1;
+	}
+	net = find_path_device("/mambo/bogus-net at 0");
+	if (net == NULL) {
+		return -1;
+	}
+	reg = (unsigned int *) get_property(net, "reg", 0);
+
+	if (*reg != devno) {
+		return -1;
+	}
+
+	return MamboBogusNetProbe( devno, buf );
+}
+
+static int
+mambonet_send(int devno, void *buf, ulong size)
+{
+	return MamboBogusNetSend(devno, buf, size);
+}
+
+static int
+mambonet_recv(int devno, void *buf, ulong size)
+{
+	return MamboBogusNetRecv(devno, buf, size);
+}
+
+static int
+mambonet_start_xmit(struct sk_buff * skb, struct net_device * dev)
+{
+	struct netdev_private *priv = (struct netdev_private
+				       *) dev->priv;
+	int             devno = priv->devno;
+
+	skb->dev = dev;
+
+	/* we might need to checksum or something */
+	mambonet_send(devno, skb->data, skb->len);
+
+	dev->last_rx = jiffies;
+	priv->stats.rx_bytes += skb->len;
+	priv->stats.tx_bytes += skb->len;
+	priv->stats.rx_packets++;
+	priv->stats.tx_packets++;
+
+	dev_kfree_skb(skb);
+
+	return (0);
+}
+
+static int
+mambonet_poll(struct net_device * dev, int *budget)
+{
+	struct netdev_private *np = dev->priv;
+	int             devno = np->devno;
+	char            buffer[1600];
+	int             ns;
+	struct sk_buff *skb;
+	int             frames = 0;
+	int             max_frames = min(*budget, dev->quota);
+	int             ret = 0;
+
+	while ((ns = mambonet_recv(devno, buffer, 1600)) > 0) {
+		if ((skb = dev_alloc_skb(ns + 2)) != NULL) {
+			skb->dev = dev;
+			skb_reserve(skb, 2);	/* 16 byte align the IP
+						 * header */
+#if HAS_IP_COPYSUM
+			eth_copy_and_sum(skb,
+					 buffer, ns, 0);
+			skb_put(skb, ns);
+#else
+			memcpy(skb_put(skb, ns),
+			       buffer, ns);
+#endif
+			skb->protocol =
+				eth_type_trans(skb, dev);
+
+			if(dev->irq) 
+				netif_receive_skb(skb);
+			else
+				netif_rx(skb);
+
+			dev->last_rx = jiffies;
+			np->stats.rx_packets++;
+			np->stats.rx_bytes += ns;
+		} else {
+			printk("Failed to allocated skbuff, "
+			       "dropping packet\n");
+			np->stats.rx_dropped++;
+			/* wait for another cycle */
+			return 1;
+		}
+		++frames;
+		if (frames > max_frames) {
+			ret = 1;
+			break;
+		}
+	}
+	*budget -= frames;
+	dev->quota -= frames;
+
+	if((!ret)&&(dev->irq))
+	  netif_rx_complete(dev);
+
+	return ret;
+}
+
+static void
+mambonet_timer(struct net_device * dev)
+{
+	int             budget = 16;
+	struct netdev_private *priv = 
+				(struct netdev_private*) dev->priv;
+				       
+	mambonet_poll(dev, &budget);
+
+	if (!priv->closing) {
+		SCHEDULE_BOTTOM_HALF(&priv->poll_task);
+	}
+}
+
+static struct net_device_stats *
+get_stats(struct net_device * dev)
+{
+	struct netdev_private *priv = 
+				(struct netdev_private *) dev->priv;
+	return (struct net_device_stats *) & (priv->stats);
+}
+
+static irqreturn_t
+mambonet_interrupt(int irq, void *dev_instance, struct pt_regs * regs)
+{
+	struct net_device *dev = dev_instance;
+	if (netif_rx_schedule_prep(dev)) {
+		__netif_rx_schedule(dev);
+	}
+	return IRQ_HANDLED;
+}
+
+static int
+mambonet_open(struct net_device * dev)
+{
+	struct netdev_private *priv;
+	int             ret = 0;
+
+	priv = dev->priv;
+
+	/*
+	 * we can't start polling in mambonet_init, because I don't think
+	 * workqueues are usable that early. so start polling now.
+	 */
+
+	if(dev->irq) {
+		ret = request_irq(dev->irq, &mambonet_interrupt, 0,
+				  dev->name, dev);
+
+		if (ret == 0) {
+			netif_start_queue(dev);
+		} else {
+			printk(KERN_ERR "mambonet: request irq failed\n");
+		}
+
+		MamboBogusNetProbe( priv->devno, NULL ); /* probe with NULL to activate interrupts */
+	} else {
+		mambonet_timer(dev);
+	}
+
+	return ret;
+}
+
+static int
+mambonet_close(struct net_device * dev)
+{
+	struct netdev_private *priv;
+
+	netif_stop_queue(dev);
+	
+	if(dev->irq)
+		free_irq(dev->irq, dev);
+
+	priv = dev->priv;
+	priv->closing = 1;
+	if(dev->irq==0) {
+		KILL_BOTTOM_HALF(&priv->poll_task);
+	}
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct net_device_stats mambonet_stats;
+
+static struct net_device_stats *
+mambonet_get_stats(struct net_device * dev)
+{
+	return &mambonet_stats;
+}
+
+static int
+mambonet_set_mac_address(struct net_device * dev, void *p)
+{
+	return -EOPNOTSUPP;
+}
+static int
+mambonet_ioctl(struct net_device * dev, struct ifreq * ifr, int cmd)
+{
+	return -EOPNOTSUPP;
+}
+static int      nextdevno = 0;	/* running count of device numbers */
+
+/* Initialize the rest of the device. */
+int             __init
+do_mambonet_probe(struct net_device * dev)
+{
+	struct netdev_private *priv;
+	int             devno = nextdevno++;
+	int             irq;
+
+	printk("eth%d: bogus network driver initialization\n", devno);
+
+	irq = mambonet_probedev(devno, dev->dev_addr);
+
+	if (irq < 0) {
+		printk("No IRQ retreived\n");
+		return (-ENODEV);
+	}
+
+	printk("%s: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", dev->name,
+	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+	SET_MODULE_OWNER(dev);
+
+	dev->irq = irq;
+	dev->mtu = MAMBO_MTU;
+	dev->open = mambonet_open;
+	dev->poll = mambonet_poll;
+	dev->weight = 16;
+	dev->stop = mambonet_close;
+	dev->hard_start_xmit = mambonet_start_xmit;
+	dev->get_stats = mambonet_get_stats;
+	dev->set_mac_address = mambonet_set_mac_address;
+	dev->do_ioctl = mambonet_ioctl;
+
+	dev->priv = kmalloc(sizeof(struct netdev_private), GFP_KERNEL);
+	if (dev->priv == NULL)
+		return -ENOMEM;
+	memset(dev->priv, 0, sizeof(struct netdev_private));
+
+	priv = dev->priv;
+	priv->devno = devno;
+	priv->closing = 0;
+	dev->get_stats = get_stats;
+
+	if(dev->irq==0) {
+		INIT_BOTTOM_HALF(&priv->poll_task, (void *) mambonet_timer, 
+						(void*) dev);
+	}		     
+
+	return (0);
+};
+
+struct net_device * __init
+mambonet_probe(int unit)
+{
+	struct net_device *dev = alloc_etherdev(0);
+	int err;
+
+	if (!dev)
+		return ERR_PTR(-ENODEV);
+
+	sprintf(dev->name, "eth%d", unit);
+	netdev_boot_setup_check(dev);
+
+	err = do_mambonet_probe(dev);
+
+	if (err)
+		goto out;
+	
+	err = register_netdev(dev);
+	if (err)
+		goto out;
+
+	return dev;
+
+out:
+	free_netdev(dev);
+	return ERR_PTR(err);
+}
+
+int __init init_mambonet(void)
+{
+        mambonet_probe(0);
+        return 0;
+}
+
+module_init(init_mambonet);
+MODULE_LICENSE("GPL");
unchanged:
--- linux-2.6.14/drivers/net/Makefile.orig	2005-11-16 01:29:02.000000000 +0000
+++ linux-2.6.14/drivers/net/Makefile	2005-11-16 01:31:33.000000000 +0000
@@ -207,4 +207,4 @@ obj-$(CONFIG_NETCONSOLE) += netconsole.o
 obj-$(CONFIG_NETDUMP) += netdump.o
 
 obj-$(CONFIG_FS_ENET) += fs_enet/
-
+obj-$(CONFIG_MAMBO_NET) += mambonet.o
unchanged:
--- linux-2.6.14-rc.orig/drivers/char/Makefile	2005-10-22 01:17:30.000000000 +0200
+++ linux-2.6.14-rc/drivers/char/Makefile	2005-10-22 01:18:12.000000000 +0200
@@ -41,5 +41,6 @@
 obj-$(CONFIG_SX)		+= sx.o generic_serial.o
 obj-$(CONFIG_RIO)		+= rio/ generic_serial.o
+obj-$(CONFIG_BOGUS_CONSOLE)	+=bogus_console.o
 obj-$(CONFIG_HVC_CONSOLE)	+= hvc_console.o hvc_vio.o hvsi.o
 obj-$(CONFIG_RAW_DRIVER)	+= raw.o
 obj-$(CONFIG_SGI_SNSC)		+= snsc.o snsc_event.o
unchanged:
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.14-rc/drivers/char/bogus_console.c	2005-10-22 01:18:12.000000000 +0200
@@ -0,0 +1,315 @@
+/*
+ * Bogus console driver using IBM Full System Simulator
+ *
+ * (C) Copyright IBM Corporation 2001-2005
+ *
+ * Bogus Console Driver
+ *
+ * Author: Maximino Aguilar <IBM STI Design Center>
+ *
+ *    inspired by drivers/char/hvc_console.c
+ *    written by Anton Blanchard and Paul Mackerras
+ *
+ * Some code is from the IBM Full System Simulator Group in ARL.
+ * Author: Patrick Bohrer <IBM Austin Research Lab>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/kdev_t.h>
+#include <linux/string.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/types.h>
+#include <linux/vt_kern.h>
+#include <linux/tty_flip.h>
+
+#define bog_console_major			240
+#define bog_console_minor			0
+#define BOG_TTY_BUF_SIZE			512
+
+static inline int callthru0(int command)
+{
+	register int c asm ("r3") = command;
+
+	asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c));
+	return((c));
+}
+
+static inline int callthru3(int command, unsigned long arg1, unsigned long arg2, unsigned long arg3)
+{
+	register int c asm ("r3") = command;
+	register unsigned long a1 asm ("r4") = arg1;
+	register unsigned long a2 asm ("r5") = arg2;
+	register unsigned long a3 asm ("r6") = arg3;
+
+	asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1), "r" (a2), "r" (a3));
+	return((c));
+}
+
+static inline int WriteConsole(char *string)
+{
+	return(callthru3(0, (unsigned long)string,
+		(unsigned long)strlen(string), (unsigned long)1));
+}
+
+static inline int ReadConsole(void)
+{
+	return(callthru0(60));
+}
+
+typedef struct {
+	struct tty_struct *tty;
+	unsigned char buf[BOG_TTY_BUF_SIZE];
+	unsigned short int buf_count;
+	spinlock_t lock;
+} bog_tty_data_struct;
+
+static bog_tty_data_struct bog_tty_data = {  };
+
+static struct tty_driver bog_tty_driver;
+static struct termios *bog_tty_termios[1];
+static struct termios *bog_tty_termios_locked[1];
+static int bog_tty_refcount = 0;
+
+static int
+bog_tty_open (struct tty_struct *tty, struct file *filp)
+{
+	if (tty->index != 0)
+		return -ENODEV;
+
+	tty->driver_data = &bog_tty_data;
+	bog_tty_data.buf_count = 0;
+	bog_tty_data.tty = tty;
+	tty->low_latency = 0;
+	bog_tty_data.buf[0]=0;
+	return 0;
+}
+
+static void
+bog_tty_close (struct tty_struct *tty, struct file *filp)
+{
+	if (tty->count > 1)
+		return;
+	bog_tty_data.tty = NULL;
+}
+
+static int
+bog_tty_write (struct tty_struct *tty, const unsigned char *buf, int count)
+{
+	return 0;
+}
+
+static int
+bog_tty_write_room (struct tty_struct *tty)
+{
+	return BOG_TTY_BUF_SIZE;
+}
+
+static void
+bog_tty_put_char (struct tty_struct *tty, unsigned char ch)
+{
+	char buff[BOG_TTY_BUF_SIZE];
+	int i;
+
+	if (bog_tty_data.buf_count >= BOG_TTY_BUF_SIZE) {
+		for (i=0;i<bog_tty_data.buf_count+1;i++)
+			buff[i]=0;
+		strncpy(buff,bog_tty_data.buf,bog_tty_data.buf_count);
+		WriteConsole(buff);
+		bog_tty_data.buf_count = 0;
+	}
+	bog_tty_data.buf[bog_tty_data.buf_count] = ch;
+	bog_tty_data.buf_count++;
+	bog_tty_data.buf[bog_tty_data.buf_count] = 0;
+}
+
+static void
+bog_tty_flush_chars (struct tty_struct *tty)
+{
+	int i;
+	char buff[BOG_TTY_BUF_SIZE];
+
+	for (i=0;i<bog_tty_data.buf_count+1;i++)
+		buff[i]=0;
+	strncpy(buff,bog_tty_data.buf,bog_tty_data.buf_count);
+	WriteConsole(buff);
+	bog_tty_data.buf_count = 0;
+}
+
+static int
+bog_tty_chars_in_buffer (struct tty_struct *tty)
+{
+	return 0;
+}
+
+static void
+bog_tty_flush_buffer (struct tty_struct *tty)
+{
+}
+
+int
+bog_tty_input (unsigned char *buf)
+{
+	struct tty_struct *tty = bog_tty_data.tty;
+	int c;
+	int bp=0;
+	int count=0;
+
+	if (tty != NULL)
+	{
+		for (;;) {
+			if (( c = ReadConsole() ) != -1) {
+				buf[bp++]=c;
+				buf[bp]='\0';
+				count++;
+			}
+			else
+				break;
+			if (count == BOG_TTY_BUF_SIZE)
+				break;
+		}
+	}
+	return count;
+}
+
+static void bog_poll(void) {
+	struct tty_struct *tty;
+	char buff[BOG_TTY_BUF_SIZE];
+	int count=0;
+	int i,rc;
+	unsigned char *charptr, *flagptr;
+
+	tty=bog_tty_data.tty;
+	if (!tty)
+		return ;
+	charptr=tty->flip.char_buf_ptr;
+	flagptr=tty->flip.flag_buf_ptr;
+	rc=tty->flip.count;
+
+	count=bog_tty_input(buff);
+	if (count!=0)
+	{
+		for (i=0;i<count;i++)
+			tty_insert_flip_char(tty,buff[i],0);
+		tty_schedule_flip(tty);
+	}
+	count=0;
+}
+
+int kbogconsd (void) {
+	daemonize("kbogconsd");
+	strcpy(current->comm,"kbogconsd");
+	sigfillset(&current->blocked);
+
+	for (;;) {
+		bog_poll();
+		set_current_state(TASK_INTERRUPTIBLE);
+		/* We schedule often to allow for a better typing experience */
+		schedule_timeout(1);
+	}
+}
+
+static struct tty_operations con_ops = {
+	.open = bog_tty_open,
+	.close = bog_tty_close,
+	.write = bog_tty_write,
+	.write_room = bog_tty_write_room,
+	.put_char = bog_tty_put_char,
+	.flush_chars = bog_tty_flush_chars,
+	.chars_in_buffer = bog_tty_chars_in_buffer,
+	.flush_buffer = bog_tty_flush_buffer,
+};
+
+int __init bog_tty_init (void)
+{
+	bog_tty_driver.magic = TTY_DRIVER_MAGIC;
+	bog_tty_driver.driver_name = "bogus";
+	bog_tty_driver.name = "bogus";
+	bog_tty_driver.name_base = 0;
+	bog_tty_driver.major = bog_console_major;
+	bog_tty_driver.minor_start = bog_console_minor;
+	bog_tty_driver.num = 1;
+	bog_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM;
+	bog_tty_driver.subtype = SYSTEM_TYPE_TTY;
+	bog_tty_driver.init_termios = tty_std_termios;
+	bog_tty_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
+	bog_tty_driver.init_termios.c_oflag = ONLCR;
+	bog_tty_driver.init_termios.c_lflag = ISIG | ECHO;
+	bog_tty_driver.flags = TTY_DRIVER_REAL_RAW;
+	bog_tty_driver.refcount = bog_tty_refcount;
+	bog_tty_driver.termios = bog_tty_termios;
+	bog_tty_driver.termios_locked = bog_tty_termios_locked;
+
+	tty_set_operations(&bog_tty_driver, &con_ops);
+
+	if (tty_register_driver(&bog_tty_driver))
+		printk(KERN_ERR "Couldn't register bog_tty driver\n");
+
+	kernel_thread((void *)kbogconsd, NULL, CLONE_KERNEL);
+	return 0;
+}
+
+static int __init bog_console_setup(struct console *co, char *options)
+{
+	return 0;
+}
+
+static void __exit bog_exit(void)
+{
+}
+
+void
+bog_console_write(struct console *console, const char *message, unsigned count)
+{
+	char buff[count+1];
+	int i;
+
+	for (i=0;i<count+1;i++)
+		buff[i]=0;
+	strncpy(buff,message,count);
+	WriteConsole(buff);
+}
+
+static struct tty_driver *bog_console_device (struct console * c, int *index)
+{
+	*index = c->index;
+	return &bog_tty_driver;
+}
+
+struct console bog_console = {
+	.name		= "bogus",
+	.write		= bog_console_write,
+	.device		= bog_console_device,
+	.setup		= bog_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+static int __init bog_console_init (void)
+{
+	register_console(&bog_console);
+	return 0;
+}
+
+console_initcall(bog_console_init);
+module_init(bog_tty_init);
+module_exit(bog_exit);
unchanged:
--- linux-2.6.14-rc.orig/drivers/char/Kconfig	2005-10-22 01:17:30.000000000 +0200
+++ linux-2.6.14-rc/drivers/char/Kconfig	2005-10-22 01:18:12.000000000 +0200
@@ -566,6 +566,12 @@
         help
           RTAS console support.
 
+config BOGUS_CONSOLE
+	bool "Simulator bogus console support"
+	depends on PPC_PSERIES || PPC_CELL
+	help
+	  IBM System Simulator bogus console device driver.
+
 config HVCS
 	tristate "IBM Hypervisor Virtual Console Server support"
 	depends on PPC_PSERIES
only in patch2:
unchanged:
--- linux-2.6.15-rc.orig/arch/powerpc/kernel/prom_init.c
+++ linux-2.6.15-rc/arch/powerpc/kernel/prom_init.c
@@ -1426,6 +1426,8 @@ static int __init prom_find_machine_type
 #ifdef CONFIG_PPC64
 			if (strstr(p, RELOC("Momentum,Maple")))
 				return PLATFORM_MAPLE;
+			if (strstr(p, RELOC("IBM,CPB")))
+				return PLATFORM_CELL;
 #endif
 			i += sl + 1;
 		}

linux-2.6.15-rc1-ppc-vdso-2.patch:
 arch/powerpc/kernel/vdso32/cacheflush.S   |    2 ++
 arch/powerpc/kernel/vdso32/datapage.S     |    2 ++
 arch/powerpc/kernel/vdso32/gettimeofday.S |    3 +++
 arch/powerpc/kernel/vdso64/cacheflush.S   |    2 ++
 arch/powerpc/kernel/vdso64/datapage.S     |    2 ++
 arch/powerpc/kernel/vdso64/gettimeofday.S |    3 +++
 include/asm-powerpc/vdso.h                |    2 +-
 7 files changed, 15 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.15-rc1-ppc-vdso-2.patch ---
>From linuxppc64-dev-bounces at ozlabs.org Tue Nov 15 06:22:12 2005
Return-path: <linuxppc64-dev-bounces at ozlabs.org>
Envelope-to: dwmw2 at baythorne.infradead.org
Delivery-date: Tue, 15 Nov 2005 06:22:12 +0000
Received: from [2002:d592:9a28::1] (helo=pentafluge.infradead.org) by
	baythorne.infradead.org with esmtps (Exim 4.54 #1 (Red Hat Linux)) id
	1EbuCq-0004Mt-Bw for dwmw2 at baythorne.infradead.org; Tue, 15 Nov 2005
	06:22:12 +0000
Received: from ozlabs.org ([203.10.76.45]) by pentafluge.infradead.org with
	esmtps (Exim 4.54 #1 (Red Hat Linux)) id 1EbuCn-00058q-6G for
	dwmw2 at infradead.org; Tue, 15 Nov 2005 06:22:11 +0000
Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix)
	with ESMTP id D55EE68776; Tue, 15 Nov 2005 17:22:04 +1100 (EST)
X-Original-To: linuxppc64-dev at ozlabs.org
Delivered-To: linuxppc64-dev at ozlabs.org
Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using
	TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not
	present a certificate) by ozlabs.org (Postfix) with ESMTP id AAB756876C for
	<linuxppc64-dev at ozlabs.org>; Tue, 15 Nov 2005 17:22:02 +1100 (EST)
Received: from gaston (localhost [127.0.0.1]) by gate.crashing.org
	(8.12.8/8.12.8) with ESMTP id jAF6JiWG015172; Tue, 15 Nov 2005 00:19:45
	-0600
From: Benjamin Herrenschmidt <benh at kernel.crashing.org>
To: Paul Mackerras <paulus at samba.org>
Content-Type: text/plain
Date: Tue, 15 Nov 2005 17:21:12 +1100
Message-Id: <1132035672.23979.14.camel at gaston>
Mime-Version: 1.0
X-Mailer: Evolution 2.2.3 
Cc: linuxppc64-dev <linuxppc64-dev at ozlabs.org>, Steve Munroe <sjmunroe at us.ibm.com>, "tom_gall at mac.com" <tom_gall at mac.com>
Subject: [PATCH] powerpc: Make the vDSO functions set error code
X-BeenThere: linuxppc64-dev at ozlabs.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: 64-bit Linux on PowerPC Developers Mail List
	<linuxppc64-dev.ozlabs.org>
List-Unsubscribe: <https://ozlabs.org/mailman/listinfo/linuxppc64-dev>,
	<mailto:linuxppc64-dev-request at ozlabs.org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc64-dev>
List-Post: <mailto:linuxppc64-dev at ozlabs.org>
List-Help: <mailto:linuxppc64-dev-request at ozlabs.org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc64-dev>,
	<mailto:linuxppc64-dev-request at ozlabs.org?subject=subscribe>
Sender: linuxppc64-dev-bounces at ozlabs.org
Errors-To: linuxppc64-dev-bounces at ozlabs.org
X-Spam-Score: 0.0 (/)
X-Evolution-Source: imap://dwmw2@baythorne.infradead.org/
Content-Transfer-Encoding: 8bit

The vDSO functions should have the same calling convention as a syscall.
Unfortunately, they currently don't set the cr0.so bit which is used to
indicate an error. This patch makes them clear this bit unconditionally
since all functions currently succeed. The syscall fallback done by some
of them will eventually override this if the syscall fails.

This also changes the symbol version of all vdso exports to make sure
glibc can differenciate between old and fixed calls for existing ones
like __kernel_gettimeofday.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---

Tom, Steve: You'll have to write a wrapper macro to call the vdso
similar to the syscall one, that does something like:

   mtctr   %0 <--- function address
   bctrl
   mfcr    %1 <--- error indication in cr0.so 

With appropriate clobbers, similar to the syscall macro (the vDSO
clobbers all volatile register (r0, r3 ... r12, cr0, cr1 and XER)

The advantage of doing so is that you don't have to create fake
descriptors for ppc64 and thus avoid useless TOC reloads, you can even
have a single macro that works on both 32 and 64 bits.

Index: linux-work/arch/powerpc/kernel/vdso32/cacheflush.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso32/cacheflush.S	2005-11-14 10:41:58.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso32/cacheflush.S	2005-11-15 17:11:51.000000000 +1100
@@ -30,6 +30,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_sync_dicache)
   .cfi_startproc
+	crclr	cr0*4+so
 	li	r5,127
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
@@ -58,6 +59,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_sync_dicache_p5)
   .cfi_startproc
+	crclr	cr0*4+so
 	sync
 	isync
 	li	r3,0
Index: linux-work/arch/powerpc/kernel/vdso32/datapage.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso32/datapage.S	2005-11-15 13:31:58.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso32/datapage.S	2005-11-15 17:10:46.000000000 +1100
@@ -52,6 +52,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_get_syscall_map)
   .cfi_startproc
+	crclr	cr0*4+so
 	mflr	r12
   .cfi_register lr,r12
 
@@ -74,6 +75,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_get_tbfreq)
   .cfi_startproc
+	crclr	cr0*4+so
 	mflr	r12
   .cfi_register lr,r12
 	bl	__get_datapage at local
Index: linux-work/arch/powerpc/kernel/vdso32/gettimeofday.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso32/gettimeofday.S	2005-11-15 13:31:58.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso32/gettimeofday.S	2005-11-15 17:10:10.000000000 +1100
@@ -26,6 +26,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_gettimeofday)
   .cfi_startproc
+	crclr	cr0*4+so
 	mflr	r12
   .cfi_register lr,r12
 
@@ -80,6 +81,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_clock_gettime)
   .cfi_startproc
+	crclr	cr0*4+so
 	/* Check for supported clock IDs */
 	cmpli	cr0,r3,CLOCK_REALTIME
 	cmpli	cr1,r3,CLOCK_MONOTONIC
@@ -211,6 +213,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_clock_getres)
   .cfi_startproc
+	crclr	cr0*4+so
 	/* Check for supported clock IDs */
 	cmpwi	cr0,r3,CLOCK_REALTIME
 	cmpwi	cr1,r3,CLOCK_MONOTONIC
Index: linux-work/arch/powerpc/kernel/vdso64/cacheflush.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso64/cacheflush.S	2005-11-14 10:41:58.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso64/cacheflush.S	2005-11-15 17:12:53.000000000 +1100
@@ -30,6 +30,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_sync_dicache)
   .cfi_startproc
+	crclr	cr0*4+so
 	li	r5,127
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
@@ -58,6 +59,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_sync_dicache_p5)
   .cfi_startproc
+	crclr	cr0*4+so
 	sync
 	isync
 	li	r3,0
Index: linux-work/arch/powerpc/kernel/vdso64/datapage.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso64/datapage.S	2005-11-15 13:31:58.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso64/datapage.S	2005-11-15 17:12:39.000000000 +1100
@@ -52,6 +52,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_get_syscall_map)
   .cfi_startproc
+	crclr	cr0*4+so
 	mflr	r12
   .cfi_register lr,r12
 
@@ -75,6 +76,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_get_tbfreq)
   .cfi_startproc
+	crclr	cr0*4+so
 	mflr	r12
   .cfi_register lr,r12
 	bl	V_LOCAL_FUNC(__get_datapage)
Index: linux-work/arch/powerpc/kernel/vdso64/gettimeofday.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso64/gettimeofday.S	2005-11-15 13:31:58.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso64/gettimeofday.S	2005-11-15 17:12:29.000000000 +1100
@@ -27,6 +27,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_gettimeofday)
   .cfi_startproc
+	crclr	cr0*4+so
 	mflr	r12
   .cfi_register lr,r12
 
@@ -66,6 +67,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_clock_gettime)
   .cfi_startproc
+	crclr	cr0*4+so
 	/* Check for supported clock IDs */
 	cmpwi	cr0,r3,CLOCK_REALTIME
 	cmpwi	cr1,r3,CLOCK_MONOTONIC
@@ -185,6 +187,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_clock_getres)
   .cfi_startproc
+	crclr	cr0*4+so
 	/* Check for supported clock IDs */
 	cmpwi	cr0,r3,CLOCK_REALTIME
 	cmpwi	cr1,r3,CLOCK_MONOTONIC
Index: linux-work/include/asm-powerpc/vdso.h
===================================================================
--- linux-work.orig/include/asm-powerpc/vdso.h	2005-11-14 10:42:00.000000000 +1100
+++ linux-work/include/asm-powerpc/vdso.h	2005-11-15 17:17:20.000000000 +1100
@@ -11,7 +11,7 @@
 #define VDSO32_MBASE	VDSO32_LBASE
 #define VDSO64_MBASE	VDSO64_LBASE
 
-#define VDSO_VERSION_STRING	LINUX_2.6.12
+#define VDSO_VERSION_STRING	LINUX_2.6.15
 
 /* Define if 64 bits VDSO has procedure descriptors */
 #undef VDS64_HAS_DESCRIPTORS


_______________________________________________
Linuxppc64-dev mailing list
Linuxppc64-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc64-dev

linux-2.6.15-rc1-ppc64-syscallpath.patch:
 arch/powerpc/kernel/asm-offsets.c |    4 
 arch/powerpc/kernel/entry_32.S    |  167 +++++++++++++++++------------
 arch/powerpc/kernel/entry_64.S    |  214 ++++++++++++++++++++------------------
 arch/powerpc/kernel/signal_32.c   |   68 +++++-------
 arch/powerpc/kernel/signal_64.c   |   23 +++-
 arch/powerpc/kernel/systbl.S      |   10 -
 include/asm-powerpc/ptrace.h      |    2 
 include/asm-powerpc/thread_info.h |   12 +-
 8 files changed, 278 insertions(+), 222 deletions(-)

--- NEW FILE linux-2.6.15-rc1-ppc64-syscallpath.patch ---
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 91538d2..3bf89d1 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -92,9 +92,9 @@ int main(void)
 
 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
 	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
-	DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
-#ifdef CONFIG_PPC32
+	DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame));
 	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+#ifdef CONFIG_PPC32
 	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
 #endif /* CONFIG_PPC32 */
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 2e99ae4..8fed953 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -200,8 +200,6 @@ _GLOBAL(DoSyscall)
 	bl	do_show_syscall
 #endif /* SHOW_SYSCALLS */
 	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
-	li	r11,0
-	stb	r11,TI_SC_NOERR(r10)
 	lwz	r11,TI_FLAGS(r10)
 	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
@@ -222,25 +220,21 @@ ret_from_syscall:
 	bl	do_show_syscall_exit
 #endif
 	mr	r6,r3
-	li	r11,-_LAST_ERRNO
-	cmplw	0,r3,r11
 	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
-	blt+	30f
-	lbz	r11,TI_SC_NOERR(r12)
-	cmpwi	r11,0
-	bne	30f
-	neg	r3,r3
-	lwz	r10,_CCR(r1)	/* Set SO bit in CR */
-	oris	r10,r10,0x1000
-	stw	r10,_CCR(r1)
-
 	/* disable interrupts so current_thread_info()->flags can't change */
-30:	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
 	SYNC
 	MTMSRD(r10)
 	lwz	r9,TI_FLAGS(r12)
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+	li	r8,-_LAST_ERRNO
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
 	bne-	syscall_exit_work
+	cmplw	0,r3,r8
+	blt+	syscall_exit_cont
+	lwz	r11,_CCR(r1)			/* Load CR */
+	neg	r3,r3
+	oris	r11,r11,0x1000	/* Set SO bit in CR */
+	stw	r11,_CCR(r1)
 syscall_exit_cont:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
 	/* If the process has its own DBCR0 value, load it up.  The single
@@ -292,46 +286,113 @@ syscall_dotrace:
 	b	syscall_dotrace_cont
 
 syscall_exit_work:
-	stw	r6,RESULT(r1)	/* Save result */
+	andi.	r0,r9,_TIF_RESTOREALL
+	bne-	2f
+	cmplw	0,r3,r8
+	blt+	1f
+	andi.	r0,r9,_TIF_NOERROR
+	bne-	1f
+	lwz	r11,_CCR(r1)			/* Load CR */
+	neg	r3,r3
+	oris	r11,r11,0x1000	/* Set SO bit in CR */
+	stw	r11,_CCR(r1)
+
+1:	stw	r6,RESULT(r1)	/* Save result */
 	stw	r3,GPR3(r1)	/* Update return value */
-	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
-	beq	5f
-	ori	r10,r10,MSR_EE
-	SYNC
-	MTMSRD(r10)		/* re-enable interrupts */
+2:	andi.	r0,r9,(_TIF_PERSYSCALL_MASK)
+	beq	4f
+
+	/* Clear per-syscall TIF flags if any are set, but _leave_
+	_TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
+	yet.  */
+
+	li	r11,_TIF_PERSYSCALL_MASK
+	addi	r12,r12,TI_FLAGS
+3:	lwarx	r8,0,r12
+	andc	r8,r8,r11
+#ifdef CONFIG_IBM405_ERR77
+	dcbt	0,r12
+#endif
+	stwcx.	r8,0,r12
+	bne-	3b
+	subi	r12,r12,TI_FLAGS
+	
+4:	/* Anything which requires enabling interrupts? */
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
+	beq	7f
+
+	/* Save NVGPRS if they're not saved already */
 	lwz	r4,_TRAP(r1)
 	andi.	r4,r4,1
-	beq	4f
+	beq	5f
 	SAVE_NVGPRS(r1)
 	li	r4,0xc00
 	stw	r4,_TRAP(r1)
-4:
+
+	/* Re-enable interrupts */
+5:	ori	r10,r10,MSR_EE
+	SYNC
+	MTMSRD(r10)
+
+	andi.	r0,r9,_TIF_SAVE_NVGPRS
+	bne	save_user_nvgprs
+
+save_user_nvgprs_cont:
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+	beq	7f
+
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	do_syscall_trace_leave
 	REST_NVGPRS(r1)
-2:
-	lwz	r3,GPR3(r1)
+
+6:	lwz	r3,GPR3(r1)
 	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
 	SYNC
 	MTMSRD(r10)		/* disable interrupts again */
 	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
 	lwz	r9,TI_FLAGS(r12)
-5:
+7:
 	andi.	r0,r9,_TIF_NEED_RESCHED
-	bne	1f
+	bne	8f
 	lwz	r5,_MSR(r1)
 	andi.	r5,r5,MSR_PR
-	beq	syscall_exit_cont
+	beq	ret_from_except
 	andi.	r0,r9,_TIF_SIGPENDING
-	beq	syscall_exit_cont
+	beq	ret_from_except
 	b	do_user_signal
-1:
+8:
 	ori	r10,r10,MSR_EE
 	SYNC
 	MTMSRD(r10)		/* re-enable interrupts */
 	bl	schedule
-	b	2b
+	b	6b
+
+save_user_nvgprs:
+	lwz	r8,TI_SIGFRAME(r12)
 
+.macro savewords start, end
+  1:	stw \start,4*(\start)(r8)
+	.section __ex_table,"a"
+	.align	2
+	.long	1b,save_user_nvgprs_fault
+	.previous
+	.if \end - \start
+	savewords "(\start+1)",\end
+	.endif
+.endm	
+	savewords 14,31
+	b	save_user_nvgprs_cont
+
+	
+save_user_nvgprs_fault:
+	li	r3,11		/* SIGSEGV */
+	lwz	r4,TI_TASK(r12)
+	bl	force_sigsegv
+
+	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
+	lwz	r9,TI_FLAGS(r12)
+	b	save_user_nvgprs_cont
+	
 #ifdef SHOW_SYSCALLS
 do_show_syscall:
 #ifdef SHOW_SYSCALLS_TASK
@@ -401,28 +462,10 @@ show_syscalls_task:
 #endif /* SHOW_SYSCALLS */
 
 /*
- * The sigsuspend and rt_sigsuspend system calls can call do_signal
- * and thus put the process into the stopped state where we might
- * want to examine its user state with ptrace.  Therefore we need
- * to save all the nonvolatile registers (r13 - r31) before calling
- * the C code.
+ * The fork/clone functions need to copy the full register set into
+ * the child process. Therefore we need to save all the nonvolatile
+ * registers (r13 - r31) before calling the C code.
  */
-	.globl	ppc_sigsuspend
-ppc_sigsuspend:
-	SAVE_NVGPRS(r1)
-	lwz	r0,_TRAP(r1)
-	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
-	stw	r0,_TRAP(r1)		/* register set saved */
-	b	sys_sigsuspend
-
-	.globl	ppc_rt_sigsuspend
-ppc_rt_sigsuspend:
-	SAVE_NVGPRS(r1)
-	lwz	r0,_TRAP(r1)
-	rlwinm	r0,r0,0,0,30
-	stw	r0,_TRAP(r1)
-	b	sys_rt_sigsuspend
-
 	.globl	ppc_fork
 ppc_fork:
 	SAVE_NVGPRS(r1)
@@ -447,14 +490,6 @@ ppc_clone:
 	stw	r0,_TRAP(r1)		/* register set saved */
 	b	sys_clone
 
-	.globl	ppc_swapcontext
-ppc_swapcontext:
-	SAVE_NVGPRS(r1)
-	lwz	r0,_TRAP(r1)
-	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
-	stw	r0,_TRAP(r1)		/* register set saved */
-	b	sys_swapcontext
-
 /*
  * Top-level page fault handling.
  * This is in assembler because if do_page_fault tells us that
@@ -626,16 +661,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
 	.long	ret_from_except
 #endif
 
-	.globl	sigreturn_exit
-sigreturn_exit:
-	subi	r1,r3,STACK_FRAME_OVERHEAD
-	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
-	lwz	r9,TI_FLAGS(r12)
-	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
-	beq+	ret_from_except_full
-	bl	do_syscall_trace_leave
-	/* fall through */
-
 	.globl	ret_from_except_full
 ret_from_except_full:
 	REST_NVGPRS(r1)
@@ -658,7 +683,7 @@ user_exc_return:		/* r10 contains MSR_KE
 	/* Check current_thread_info()->flags */
 	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
 	lwz	r9,TI_FLAGS(r9)
-	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
 	bne	do_work
 
 restore_user:
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2d22bf0..83b9edf 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -113,9 +113,7 @@ system_call_common:
 	addi	r9,r1,STACK_FRAME_OVERHEAD
 #endif
 	clrrdi	r11,r1,THREAD_SHIFT
-	li	r12,0
 	ld	r10,TI_FLAGS(r11)
-	stb	r12,TI_SC_NOERR(r11)
 	andi.	r11,r10,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
 syscall_dotrace_cont:
@@ -144,24 +142,12 @@ system_call:			/* label this so stack tr
 	bctrl			/* Call handler */
 
 syscall_exit:
+	std	r3,RESULT(r1)
 #ifdef SHOW_SYSCALLS
-	std	r3,GPR3(r1)
 	bl	.do_show_syscall_exit
-	ld	r3,GPR3(r1)
+	ld	r3,RESULT(r1)
 #endif
-	std	r3,RESULT(r1)
-	ld	r5,_CCR(r1)
-	li	r10,-_LAST_ERRNO
-	cmpld	r3,r10
 	clrrdi	r12,r1,THREAD_SHIFT
-	bge-	syscall_error
-syscall_error_cont:
-
-	/* check for syscall tracing or audit */
-	ld	r9,TI_FLAGS(r12)
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
-	bne-	syscall_exit_trace
-syscall_exit_trace_cont:
 
 	/* disable interrupts so current_thread_info()->flags can't change,
 	   and so that we don't get interrupted after loading SRR0/1. */
@@ -173,8 +159,13 @@ syscall_exit_trace_cont:
 	rotldi	r10,r10,16
 	mtmsrd	r10,1
 	ld	r9,TI_FLAGS(r12)
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+	li	r11,-_LAST_ERRNO
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR)
 	bne-	syscall_exit_work
+	cmpld	r3,r11
+	ld	r5,_CCR(r1)
+	bge-	syscall_error
+syscall_error_cont:
 	ld	r7,_NIP(r1)
 	stdcx.	r0,0,r1			/* to clear the reservation */
 	andi.	r6,r8,MSR_PR
@@ -193,21 +184,12 @@ syscall_exit_trace_cont:
 	rfid
 	b	.	/* prevent speculative execution */
 
-syscall_enosys:
-	li	r3,-ENOSYS
-	std	r3,RESULT(r1)
-	clrrdi	r12,r1,THREAD_SHIFT
-	ld	r5,_CCR(r1)
-
-syscall_error:
-	lbz	r11,TI_SC_NOERR(r12)
-	cmpwi	0,r11,0
-	bne-	syscall_error_cont
-	neg	r3,r3
+syscall_error:	
 	oris	r5,r5,0x1000	/* Set SO bit in CR */
+	neg	r3,r3
 	std	r5,_CCR(r1)
 	b	syscall_error_cont
-        
+	
 /* Traced system call support */
 syscall_dotrace:
 	bl	.save_nvgprs
@@ -225,21 +207,69 @@ syscall_dotrace:
 	ld	r10,TI_FLAGS(r10)
 	b	syscall_dotrace_cont
 
-syscall_exit_trace:
-	std	r3,GPR3(r1)
-	bl	.save_nvgprs
+syscall_enosys:
+	li	r3,-ENOSYS
+	b	syscall_exit
+	
+syscall_exit_work:
+	/* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr.
+	 If TIF_NOERROR is set, just save r3 as it is. */
+
+	andi.	r0,r9,_TIF_RESTOREALL
+	bne-	2f
+	cmpld	r3,r11		/* r10 is -LAST_ERRNO */
+	blt+	1f
+	andi.	r0,r9,_TIF_NOERROR
+	bne-	1f
+	ld	r5,_CCR(r1)
+	neg	r3,r3
+	oris	r5,r5,0x1000	/* Set SO bit in CR */
+	std	r5,_CCR(r1)
+1:	std	r3,GPR3(r1)
+2:	andi.	r0,r9,(_TIF_PERSYSCALL_MASK)
+	beq	4f
+
+	/* Clear per-syscall TIF flags if any are set, but _leave_
+	_TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
+	yet.  */
+
+	li	r11,_TIF_PERSYSCALL_MASK
+	addi	r12,r12,TI_FLAGS
+3:	ldarx	r10,0,r12
+	andc	r10,r10,r11
+	stdcx.	r10,0,r12
+	bne-	3b
+	subi	r12,r12,TI_FLAGS
+	
+4:	bl	.save_nvgprs
+	/* Anything else left to do? */
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
+	beq	.ret_from_except_lite
+
+	/* Re-enable interrupts */
+	mfmsr	r10
+	ori	r10,r10,MSR_EE
+	mtmsrd	r10,1
+
+	andi.	r0,r9,_TIF_SAVE_NVGPRS
+	bne	save_user_nvgprs
+
+	/* If tracing, re-enable interrupts and do it */
+save_user_nvgprs_cont:	
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+	beq	5f
+	
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_syscall_trace_leave
 	REST_NVGPRS(r1)
-	ld	r3,GPR3(r1)
-	ld	r5,_CCR(r1)
 	clrrdi	r12,r1,THREAD_SHIFT
-	b	syscall_exit_trace_cont
 
-/* Stuff to do on exit from a system call. */
-syscall_exit_work:
-	std	r3,GPR3(r1)
-	std	r5,_CCR(r1)
+	/* Disable interrupts again and handle other work if any */
+5:	mfmsr	r10
+	rldicl	r10,r10,48,1
+	rotldi	r10,r10,16
+	mtmsrd	r10,1
+
 	b	.ret_from_except_lite
 
 /* Save non-volatile GPRs, if not already saved. */
@@ -252,6 +282,52 @@ _GLOBAL(save_nvgprs)
 	std	r0,_TRAP(r1)
 	blr
 
+
+save_user_nvgprs:
+	ld	r10,TI_SIGFRAME(r12)
+	andi.	r0,r9,_TIF_32BIT
+	beq-	save_user_nvgprs_64
+
+	/* 32-bit save to userspace */
+
+.macro savewords start, end
+  1:	stw \start,4*(\start)(r10)
+	.section __ex_table,"a"
+	.align	3
+	.llong	1b,save_user_nvgprs_fault
+	.previous
+	.if \end - \start
+	savewords "(\start+1)",\end
+	.endif
+.endm	
+	savewords 14,31
+	b	save_user_nvgprs_cont
+
+save_user_nvgprs_64:
+	/* 64-bit save to userspace */
+
+.macro savelongs start, end
+  1:	std \start,8*(\start)(r10)
+	.section __ex_table,"a"
+	.align	3
+	.llong	1b,save_user_nvgprs_fault
+	.previous
+	.if \end - \start
+	savelongs "(\start+1)",\end
+	.endif
+.endm	
+	savelongs 14,31
+	b	save_user_nvgprs_cont
+
+save_user_nvgprs_fault:
+	li	r3,11		/* SIGSEGV */
+	ld	r4,TI_TASK(r12)
+	bl	.force_sigsegv
+
+	clrrdi	r12,r1,THREAD_SHIFT
+	ld	r9,TI_FLAGS(r12)
+	b	save_user_nvgprs_cont
+	
 /*
  * The sigsuspend and rt_sigsuspend system calls can call do_signal
  * and thus put the process into the stopped state where we might
@@ -260,35 +336,6 @@ _GLOBAL(save_nvgprs)
  * the C code.  Similarly, fork, vfork and clone need the full
  * register state on the stack so that it can be copied to the child.
  */
-_GLOBAL(ppc32_sigsuspend)
-	bl	.save_nvgprs
-	bl	.compat_sys_sigsuspend
-	b	70f
-
-_GLOBAL(ppc64_rt_sigsuspend)
-	bl	.save_nvgprs
-	bl	.sys_rt_sigsuspend
-	b	70f
-
-_GLOBAL(ppc32_rt_sigsuspend)
-	bl	.save_nvgprs
-	bl	.compat_sys_rt_sigsuspend
-70:	cmpdi	0,r3,0
-	/* If it returned an error, we need to return via syscall_exit to set
-	   the SO bit in cr0 and potentially stop for ptrace. */
-	bne	syscall_exit
-	/* If sigsuspend() returns zero, we are going into a signal handler. We
-	   may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
-#ifdef CONFIG_AUDITSYSCALL
-	ld	r3,PACACURRENT(r13)
-	ld	r4,AUDITCONTEXT(r3)
-	cmpdi	0,r4,0
-	beq	.ret_from_except	/* No audit_context: Leave immediately. */
-	li	r4, 2			/* AUDITSC_FAILURE */
-	li	r5,-4			/* It's always -EINTR */
-	bl	.audit_syscall_exit
-#endif
-	b	.ret_from_except
 
 _GLOBAL(ppc_fork)
 	bl	.save_nvgprs
@@ -305,37 +352,6 @@ _GLOBAL(ppc_clone)
 	bl	.sys_clone
 	b	syscall_exit
 
-_GLOBAL(ppc32_swapcontext)
-	bl	.save_nvgprs
-	bl	.compat_sys_swapcontext
-	b	80f
-	
-_GLOBAL(ppc64_swapcontext)
-	bl	.save_nvgprs
-	bl	.sys_swapcontext
-	b	80f
-
-_GLOBAL(ppc32_sigreturn)
-	bl	.compat_sys_sigreturn
-	b	80f
-
-_GLOBAL(ppc32_rt_sigreturn)
-	bl	.compat_sys_rt_sigreturn
-	b	80f
-
-_GLOBAL(ppc64_rt_sigreturn)
-	bl	.sys_rt_sigreturn
-
-80:	cmpdi	0,r3,0
-	blt	syscall_exit
-	clrrdi	r4,r1,THREAD_SHIFT
-	ld	r4,TI_FLAGS(r4)
-	andi.	r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
-	beq+	81f
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.do_syscall_trace_leave
-81:	b	.ret_from_except
-
 _GLOBAL(ret_from_fork)
 	bl	.schedule_tail
 	REST_NVGPRS(r1)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 5a2eba6..c9d0275 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -76,7 +76,6 @@
  * registers from *regs.  This is what we need
  * to do when a signal has been delivered.
  */
-#define sigreturn_exit(regs)	return 0
 
 #define GP_REGS_SIZE	min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
 #undef __SIGNAL_FRAMESIZE
@@ -156,9 +155,17 @@ static inline int save_general_regs(stru
 	elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
 	int i;
 
-	for (i = 0; i <= PT_RESULT; i ++)
+	if (!FULL_REGS(regs)) {
+		set_thread_flag(TIF_SAVE_NVGPRS);
+		current_thread_info()->nvgprs_frame = frame->mc_gregs;
+	}
+
+	for (i = 0; i <= PT_RESULT; i ++) {
+		if (i == 14 && !FULL_REGS(regs))
+			i = 32;
 		if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
 			return -EFAULT;
+	}
 	return 0;
 }
 
@@ -179,8 +186,6 @@ static inline int restore_general_regs(s
 
 #else /* CONFIG_PPC64 */
 
-extern void sigreturn_exit(struct pt_regs *);
-
 #define GP_REGS_SIZE	min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
 
 static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
@@ -219,5 +219,14 @@ static inline int get_old_sigaction(stru
 static inline int save_general_regs(struct pt_regs *regs,
 		struct mcontext __user *frame)
 {
+	if (!FULL_REGS(regs)) {
+		/* Zero out the unsaved GPRs to avoid information
+		   leak, and set TIF_SAVE_NVGPRS to ensure that the
+		   registers do actually get saved later. */
+		memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
+		current_thread_info()->nvgprs_frame = &frame->mc_gregs;
+		set_thread_flag(TIF_SAVE_NVGPRS);
+	}
+
 	return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
 }
@@ -256,8 +261,10 @@ long sys_sigsuspend(old_sigset_t mask, i
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
-		if (do_signal(&saveset, regs))
-			sigreturn_exit(regs);
+		if (do_signal(&saveset, regs)) {
+			set_thread_flag(TIF_RESTOREALL);
+			return 0;
+		}
 	}
 }
 
@@ -292,8 +299,10 @@ long sys_rt_sigsuspend(
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
-		if (do_signal(&saveset, regs))
-			sigreturn_exit(regs);
+		if (do_signal(&saveset, regs)) {
+			set_thread_flag(TIF_RESTOREALL);
+			return 0;
+		}
 	}
 }
 
@@ -391,9 +400,6 @@ struct rt_sigframe {
 static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 		int sigret)
 {
-#ifdef CONFIG_PPC32
-	CHECK_FULL_REGS(regs);
-#endif
 	/* Make sure floating point registers are stored in regs */
 	flush_fp_to_thread(current);
 
@@ -828,12 +834,6 @@ static int handle_rt_signal(unsigned lon
 	regs->gpr[6] = (unsigned long) rt_sf;
 	regs->nip = (unsigned long) ka->sa.sa_handler;
 	regs->trap = 0;
-#ifdef CONFIG_PPC64
-	regs->result = 0;
-
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-#endif
 	return 1;
 
 badframe:
@@ -911,8 +911,8 @@ long sys_swapcontext(struct ucontext __u
 	 */
 	if (do_setcontext(new_ctx, regs, 0))
 		do_exit(SIGSEGV);
-	sigreturn_exit(regs);
-	/* doesn't actually return back to here */
+
+	set_thread_flag(TIF_RESTOREALL);
 	return 0;
 }
 
@@ -945,12 +945,11 @@ long sys_rt_sigreturn(int r3, int r4, in
 	 * nobody does any...
 	 */
 	compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
-	return (int)regs->result;
 #else
 	do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
-	sigreturn_exit(regs);		/* doesn't return here */
-	return 0;
 #endif
+	set_thread_flag(TIF_RESTOREALL);
+	return 0;
 
  bad:
 	force_sig(SIGSEGV, current);
@@ -1041,9 +1040,7 @@ int sys_debug_setcontext(struct ucontext
 	 */
 	do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
 
-	sigreturn_exit(regs);
-	/* doesn't actually return back to here */
-
+	set_thread_flag(TIF_RESTOREALL);
  out:
 	return 0;
 }
@@ -1107,12 +1104,6 @@ static int handle_signal(unsigned long s
 	regs->gpr[4] = (unsigned long) sc;
 	regs->nip = (unsigned long) ka->sa.sa_handler;
 	regs->trap = 0;
-#ifdef CONFIG_PPC64
-	regs->result = 0;
-
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-#endif
 
 	return 1;
 
@@ -1160,12 +1151,8 @@ long sys_sigreturn(int r3, int r4, int r
 	    || restore_user_regs(regs, sr, 1))
 		goto badframe;
 
-#ifdef CONFIG_PPC64
-	return (int)regs->result;
-#else
-	sigreturn_exit(regs);		/* doesn't return */
+	set_thread_flag(TIF_RESTOREALL);
 	return 0;
-#endif
 
 badframe:
 	force_sig(SIGSEGV, current);
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 1decf27..5462bef 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -96,8 +96,10 @@ long sys_rt_sigsuspend(sigset_t __user *
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
-		if (do_signal(&saveset, regs))
+		if (do_signal(&saveset, regs)) {
+			set_thread_flag(TIF_RESTOREALL);
 			return 0;
+		}
 	}
 }
 
@@ -152,6 +154,14 @@ static long setup_sigcontext(struct sigc
 	err |= __put_user(0, &sc->v_regs);
 #endif /* CONFIG_ALTIVEC */
 	err |= __put_user(&sc->gp_regs, &sc->regs);
+	if (!FULL_REGS(regs)) {
+		/* Zero out the unsaved GPRs to avoid information
+		   leak, and set TIF_SAVE_NVGPRS to ensure that the
+		   registers do actually get saved later. */
+		memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
+		set_thread_flag(TIF_SAVE_NVGPRS);
+		current_thread_info()->nvgprs_frame = &sc->gp_regs;
+	}
 	err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
 	err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
 	err |= __put_user(signr, &sc->signal);
@@ -340,6 +350,7 @@ int sys_swapcontext(struct ucontext __us
 		do_exit(SIGSEGV);
 
 	/* This returns like rt_sigreturn */
+	set_thread_flag(TIF_RESTOREALL);
 	return 0;
 }
 
@@ -372,7 +383,8 @@ int sys_rt_sigreturn(unsigned long r3, u
 	 */
 	do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]);
 
-	return regs->result;
+	set_thread_flag(TIF_RESTOREALL);
+	return 0;
 
 badframe:
 #if DEBUG_SIG
@@ -454,9 +466,6 @@ static int setup_rt_frame(int signr, str
 	if (err)
 		goto badframe;
 
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-
 	return 1;
 
 badframe:
@@ -502,6 +511,8 @@ static inline void syscall_restart(struc
 		 * we only get here if there is a handler, we dont restart.
 		 */
 		regs->result = -EINTR;
+		regs->gpr[3] = EINTR;
+		regs->ccr |= 0x10000000;
 		break;
 	case -ERESTARTSYS:
 		/* ERESTARTSYS means to restart the syscall if there is no
@@ -509,6 +520,8 @@ static inline void syscall_restart(struc
 		 */
 		if (!(ka->sa.sa_flags & SA_RESTART)) {
 			regs->result = -EINTR;
+			regs->gpr[3] = EINTR;
+			regs->ccr |= 0x10000000;
 			break;
 		}
 		/* fallthrough */
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 65eaea9..4bb3650 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -113,7 +113,7 @@ SYSCALL(sgetmask)
 COMPAT_SYS(ssetmask)
 SYSCALL(setreuid)
 SYSCALL(setregid)
-SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend)
+SYS32ONLY(sigsuspend)
 COMPAT_SYS(sigpending)
 COMPAT_SYS(sethostname)
 COMPAT_SYS(setrlimit)
@@ -160,7 +160,7 @@ SYSCALL(swapoff)
 COMPAT_SYS(sysinfo)
 COMPAT_SYS(ipc)
 SYSCALL(fsync)
-SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn)
+SYS32ONLY(sigreturn)
 PPC_SYS(clone)
 COMPAT_SYS(setdomainname)
 PPC_SYS(newuname)
@@ -213,13 +213,13 @@ COMPAT_SYS(nfsservctl)
 SYSCALL(setresgid)
 SYSCALL(getresgid)
 COMPAT_SYS(prctl)
-SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn)
+COMPAT_SYS(rt_sigreturn)
 COMPAT_SYS(rt_sigaction)
 COMPAT_SYS(rt_sigprocmask)
 COMPAT_SYS(rt_sigpending)
 COMPAT_SYS(rt_sigtimedwait)
 COMPAT_SYS(rt_sigqueueinfo)
-SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend)
+COMPAT_SYS(rt_sigsuspend)
 COMPAT_SYS(pread64)
 COMPAT_SYS(pwrite64)
 SYSCALL(chown)
@@ -290,7 +290,7 @@ COMPAT_SYS(clock_settime)
 COMPAT_SYS(clock_gettime)
 COMPAT_SYS(clock_getres)
 COMPAT_SYS(clock_nanosleep)
-SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext)
+COMPAT_SYS(swapcontext)
 COMPAT_SYS(tgkill)
 COMPAT_SYS(utimes)
 COMPAT_SYS(statfs64)
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 1f7ecdb..9c550b3 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -87,7 +87,7 @@ extern unsigned long profile_pc(struct p
 
 #define force_successful_syscall_return()   \
 	do { \
-		current_thread_info()->syscall_noerror = 1; \
+		set_thread_flag(TIF_NOERROR); \
 	} while(0)
 
 /*
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index e525f49..ac1e80e 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -37,8 +37,7 @@ struct thread_info {
 	int		preempt_count;		/* 0 => preemptable,
 						   <0 => BUG */
 	struct restart_block restart_block;
-	/* set by force_successful_syscall_return */
-	unsigned char	syscall_noerror;
+	void *nvgprs_frame;
 	/* low level flags - has atomic operations done on it */
 	unsigned long	flags ____cacheline_aligned_in_smp;
 };
@@ -123,6 +122,9 @@ static inline struct thread_info *curren
 #define TIF_SINGLESTEP		9	/* singlestepping active */
 #define TIF_MEMDIE		10
 #define TIF_SECCOMP		11	/* secure computing */
+#define TIF_RESTOREALL		12	/* Restore all regs (implies NOERROR) */
+#define TIF_SAVE_NVGPRS		13	/* Save r14-r31 in signal frame */
+#define TIF_NOERROR		14	/* Force successful syscall return */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
@@ -136,10 +138,14 @@ static inline struct thread_info *curren
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
+#define _TIF_RESTOREALL		(1<<TIF_RESTOREALL)
+#define _TIF_SAVE_NVGPRS	(1<<TIF_SAVE_NVGPRS)
+#define _TIF_NOERROR		(1<<TIF_NOERROR)
 #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 #define _TIF_USER_WORK_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
-				 _TIF_NEED_RESCHED)
+				 _TIF_NEED_RESCHED | _TIF_RESTOREALL)
+#define _TIF_PERSYSCALL_MASK	(_TIF_RESTOREALL|_TIF_NOERROR|_TIF_SAVE_NVGPRS)
 
 #endif /* __KERNEL__ */
 


--- NEW FILE mirrors ---
http://ftp.kernel.org/pub/linux/kernel/v2.6/snapshots/
http://ftp.kernel.org/pub/linux/kernel/v2.6/
http://ftp.kernel.org/pub/linux/kernel/v2.6/snapshots/old/
http://ftp.kernel.org/pub/linux/kernel/v2.6/testing/


--- NEW FILE patch-2.6.15-rc4-git1.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBDkAFdyGugalF9Dw4RAq25AJwP14sihd8NGjisueVdznZBaASXQwCeJ1SD
6mCD7GhIIdQr/gZ3LhJ8+TI=
=xvqO
-----END PGP SIGNATURE-----


--- NEW FILE patch-2.6.15-rc4.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBDjqBcyGugalF9Dw4RAh5OAJ0e0GXTFElIhacdeIV5T8DL7hXAFwCfcBc/
LKVWhr4zX3c/CZTOzBRBZZ4=
=S80h
-----END PGP SIGNATURE-----


--- NEW FILE upstream ---
linux-2.6.14.tar.bz2
patch-2.6.15-rc4.bz2
patch-2.6.15-rc4-git1.bz2


--- NEW FILE upstream-key.gpg ---
pub  1024D/517D0F0E 2000-10-10 Linux Kernel Archives Verification Key <ftpadmin at kernel.org>
     Key fingerprint = C75D C40A 11D7 AF88 9981  ED5B C86B A06A 517D 0F0E
sub  4096g/E50A8F2A 2000-10-10

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.0.3 (GNU/Linux)
Comment: For info see http://www.gnupg.org

mQGiBDnirDkRBADCTL/iUTeZKb0tiAcKdZdsUP/KSnrGGjlinolUAsUC0D6/hUB1
RdCpJOOERTIEr1yvehqDM7veRhNMoxJNQxa/sSrkywey5qc8uaskUNEqenimq/70
bahWJeoWXjad68mQFh65lULnHQrrioeJnh9UpyGJppNb/yIjdnymH9aYEwCglgP7
UegBzH22h8NVQEK2PWWbyUUD/jQA4lI0wRWcL9HpkYkHcH0LTKRB9zYpQYtyvzJi
yTGwJyFMfYNXy0RT11dICeLkf3HMR84hkPERKMhALobLxVUbfc7j2AygmzGphWGy
DH/xjptQP/zrsq87ylYRONK18w1J42cm+yZa4XThMDPJMrb9/l8qnxU1JnW7W1al
HKTpBACbs+91KLqrnIGcF44TMwxgUj5CUrayPoEnLU+ZMBqfSjmu8RqEYmTxJCKv
7erBFSuazBGj5X7twunrtrW3bxO63MbLbHjfXSRrMnKOb8dRULIg6eWAnoAx8VVZ
YjrOpwAntU3WxYOpbiCHt9kLbb+N5rvNtFcmOqRRQaCIUFOOaLQ8TGludXggS2Vy
bmVsIEFyY2hpdmVzIFZlcmlmaWNhdGlvbiBLZXkgPGZ0cGFkbWluQGtlcm5lbC5v
cmc+iFUEExECABUFAjnirDkDCwoDAxUDAgMWAgECF4AACgkQyGugalF9Dw4MNACe
JiQTyCmQzPGou2cl/RyOXj79kYYAnAsT6xt72hp/PFiywYM9vBsDVv9niQEVAwUQ
OeKwNWx5eAAqlgcFAQEdZgf/Vn2dMKrn8021NhavP0uA3pHGRmdKQ2WJBdLiN2tv
LkpAioZtho+op+xBz8j1zdIJQ/7XWko869KHge2BAFwA8rWDzjtaAWdE0Jo/NiAR
epUwV2FdRRwSxIcNG2CCPyJnfPokRqjdl2z9k2PkwidHSq+2k6JxCWnOcIXChSKf
kHnemtA65ixAlhuxvyN3MPuYs1jAHyDGcyMfomp1qH9tXFQhhyXRrG2eMAfslstC
XGXLcoLN3O2BMR/fG2GlV6kOqGOvoMIW3clVeQLQ9B1yyekKiVY6Vg+CgK5qhg8z
9tjH4f33zzNDwsx1WSCOU/1LIPzFBNbR9QtTF2XmOUfRs4hGBBARAgAGBQI54rBc
AAoJEH2d7s4ry8YhmjsAoMUW9RxfXBSos0A6LwGd+5pXv/MRAKCYFLG2T4GSV+qf
iRsXnrgDHQHD04hGBBARAgAGBQI54rOZAAoJEPKlddweGoeC/+sAoL5f7JF21mRe
Z8VV4nhh7prm+idSAKCMXDWW/tBOeJDYpiEhgyGSGgJJWrkEDQQ54q+cEBAAjRmb
txamcZ9EYsQTnQvVL2l6vY5Rnbc1JDdcyHEV1kH5OwZWqvckL4QgKKBbTQwyB9pC
o0nGK4PkBbrwL0outfHQ5jl9DUzTKIu+asWUyf3fxfUV6j2A6BMo59KNnJzUyJ2+
B5na6NN8nEqEtmogROtjT8LkOvYwqD4A/5re2vwtie+h5yU6A+JbyGQF6lFxThZj
4WGctBgCcDBqRkPAG8DFFAdeN5SMAArktCYuUGXi2q88EDoOs3Ykw0kB8+ZFECz/
4/b93so5Wt2hC15cxAJoXFfR3mXHm40EHzMdEublWV4blB2KvFocQC74/H74QPUk
cWlc6EhPodKvcuOfTimDxXaiGNFONUPgNAmCXeVoOapdWpb3x7iOHPwSaXeJSrO9
fc4GtVjDv90DT2ekK7cvYk8s6B3t7p7W21Xi+hRgrw63B3HElr01gdMZY5XA5ey/
WmnyBS6LOxXlnVBE+2uSQ+aZHqrLpXcRvq2ZonOziDSE0i940ZvIwlSzn0U5BQWl
9hBDQw78RacYqaFvlpcGiPj75bScB4eemxV6Wdo9mtK0Vrr+9bWScXHEv7did4X+
7tBWKbA8M+g290OSzjeQBGLuPmbjxzEKH9jcUumzBzzC5x5GFh7On9TLXQ4K/oRT
6QQpS93YrTVbR60G4MKsePWLJmg7IgYUtNdLGjsAAwUP/0aAAq8CmWtourj1XxNY
pFmOAU45d65fPWVadKyF++B+uDyRNYN7HQCqrJ7ddn0sH7OBtlE8yaBYgR0TFly9
9+LqQO4r4IGCw2TBgA5tKnOWoPGEzvrLeoxR3SnPrKBlDvx6Rr9h3OJ9UV5u/NLh
mCP9iN10gWCGzsWbONc6qD6PugbTur44D6s4CRK9xfliSrtG3GBHW914UKjJeB9s
e3oc1rkmNv39kKcu33w4XVETAj4qpXnwoJvy639dfvnQt1TWFjIt20iP7m+jkT3B
b526uJ5GuJl6r8sm5OYYRs5cLigvUzRZVgYnjjqlRRACx0WcinKK55Li2Pq4qcRV
vSE5Tr3kTUTGxdmy113FbscrhLhesGALv3Hb7jeeWC8jviGEaHppgUumR6v0hsI1
rZ3K8kCjFRAYV8OKtcEeMqjouArGi5dn0ClmG4lwH4SEdqC/TRNWGG+iVpWf5yCj
9mvtvUhLtl6QjXHLrJdSGyafvqR1EQMJadFt4URvx0M7tqZIcwPUnb+7Oc+J96po
e/EQmnm6rFnTpWz0BbY4mbJC7vUH4JyLs0nlxiKrBjaO9C1DSAKBpjqaga8dQe1Z
kLOI2F7IWFeKV2LaMl+ZvvfWMECNcqNW2fkCuP9Fpz5K+xg21TwovVy93aWKgFL6
06jK51oQp3fW86xXK9ZGKYqQiEYEGBECAAYFAjnir5wACgkQyGugalF9Dw5M9QCg
hhmHalzWf8B3AVrjPrtrRHA1vlgAn3YRlU5l0V5W1iXvHXQCUHIESpgm
=SZZb
-----END PGP PUBLIC KEY BLOCK-----


Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/kernel-xen/devel/.cvsignore,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -r1.3 -r1.3.2.1
--- .cvsignore	9 Nov 2005 22:43:07 -0000	1.3
+++ .cvsignore	2 Dec 2005 22:11:30 -0000	1.3.2.1
@@ -1 +1,4 @@
-xen-20051109.tar.gz
+linux-2.6.14.tar.bz2
+patch-2.6.15-rc4-git1.bz2
+patch-2.6.15-rc4.bz2
+xen-20051202.tar.gz


Index: Makefile
===================================================================
RCS file: /cvs/dist/rpms/kernel-xen/devel/Makefile,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
--- Makefile	21 Oct 2005 17:41:29 -0000	1.1
+++ Makefile	2 Dec 2005 22:11:30 -0000	1.1.2.1
@@ -1,6 +1,29 @@
-# Makefile for source rpm: kernel-xen
+# Makefile for source rpm: kernel
 # $Id$
-NAME := kernel-xen
-SPECFILE = $(firstword $(wildcard *.spec))
+NAME     := kernel-xen
+SPECFILE  = $(firstword $(wildcard *.spec))
+
+# use noarch for make prep instead of the current CPU
+# noarch creates and checks all config files not just the current one,
+# in addition "i386" isn't a valid kernel target
+PREPARCH  = noarch
+
+# we only check the .sign signatures
+UPSTREAM_CHECKS = sign
+
+# local targets we need to carry around in addition to the default sources
+TARGETS		= configs download
 
 include ../common/Makefile.common
+include Makefile.config
+
+hammer: x86_64
+
+debug:
+	@perl -pi -e 's/# CONFIG_DEBUG_SLAB is not set/CONFIG_DEBUG_SLAB=y/' configs/config-generic
+	@perl -pi -e 's/# CONFIG_DEBUG_PAGEALLOC is not set/CONFIG_DEBUG_PAGEALLOC=y/' configs/config-x86-generic
+
+release:
+	@perl -pi -e 's/CONFIG_DEBUG_SLAB=y/# CONFIG_DEBUG_SLAB is not set/' configs/config-generic
+	@perl -pi -e 's/CONFIG_DEBUG_PAGEALLOC=y/# CONFIG_DEBUG_PAGEALLOC is not set/' configs/config-x86-generic
+


View full diff with command:
/usr/bin/cvs -f diff  -kk -u -N -r 1.13 -r 1.13.2.1 kernel-xen.spec
Index: kernel-xen.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel-xen/devel/kernel-xen.spec,v
retrieving revision 1.13
retrieving revision 1.13.2.1
diff -u -r1.13 -r1.13.2.1
--- kernel-xen.spec	10 Nov 2005 02:57:03 -0000	1.13
+++ kernel-xen.spec	2 Dec 2005 22:11:30 -0000	1.13.2.1
@@ -1,4 +1,15 @@
-Summary: Older kernel (temporary) to enable xen packages for rawhide
+Summary: Xen kernel+hypervisor packages for rawhide
+
+# What parts do we want to build?  We must build at least one kernel.
+# These are the kernels that are built IF the architecture allows it.
+
+%define buildup 0
+%define buildsmp 1
+%define includexen 1
+%define builddoc 0
+%define buildkdump 0
+
+# Versions of various parts
 
 #
 # Polite request for people who spin their own kernel rpms:
@@ -6,33 +17,106 @@
 # that the kernel isn't the stock distribution kernel, for example by
 # adding some text to the end of the version number.
 #
-%define sublevel 12
+%define sublevel 14
 %define kversion 2.6.%{sublevel}
 %define rpmversion 2.6.%{sublevel}
 %define rhbsys  %([ -r /etc/beehive-root -o -n "%{?__beehive_build}" ] && echo || echo .`whoami`)
 %define release %(R="$Revision$"; RR="${R##: }"; echo ${RR%%?})_FC5%{rhbsys}
+%define signmodules 0
 %define make_target bzImage
+%define kernel_image arch/$Arch/boot/bzImage
+
 %define KVERREL %{PACKAGE_VERSION}-%{PACKAGE_RELEASE}
 
 # groups of related archs
-%define all_x86 i686
+%define all_x86 i586 i686
 
 # Override generic defaults with per-arch defaults 
 
 %ifarch noarch
+%define builddoc 1
+%define buildup 0
+%define buildsmp 0
 %define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-*.config
 %endif
 
 # Second, per-architecture exclusions (ifarch)
 
+%ifarch i586
+%define buildsmp 0
+%endif
+
+%ifarch i686
+%define buildxen %{includexen}
+%define buildkdump 1
+%else
+%define buildxen 0
+%endif
+
 %ifarch %{all_x86}
 %define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-i?86*.config
 %define image_install_path boot
+%define signmodules 1
 %endif
 
 %ifarch x86_64
+%define buildsmp 0
 %define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-x86_64*.config
 %define image_install_path boot
+%define signmodules 1
+%endif
+
+%ifarch ppc64
+%define buildsmp 0
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-ppc64*.config
+%define image_install_path boot
+%define signmodules 1
+%define make_target vmlinux
+%define kernel_image vmlinux
+%endif
+
+%ifarch ppc64iseries
+%define buildsmp 0
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-ppc64*.config
+%define image_install_path boot
+%define signmodules 1
+%define make_target vmlinux
+%define kernel_image vmlinux
+%endif
+
+%ifarch s390
+%define buildsmp 0
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-s390*.config
+%define image_install_path boot
+%endif
+
+%ifarch s390x
+%define buildsmp 0
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-s390x.config
+%define image_install_path boot
+%endif
+
+%ifarch sparc
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-sparc.config
+%define buildsmp 0
+%endif
+
+%ifarch sparc64
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-sparc64*.config
+%endif
+
+%ifarch ppc
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-ppc*.config
+%define image_install_path boot
+%define make_target vmlinux
+%define kernel_image vmlinux
+%endif
+
+%ifarch ia64
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-ia64.config
+%define buildsmp 0
+%define image_install_path boot/efi/EFI/redhat
+%define signmodules 1
 %endif
 
 #
@@ -52,7 +136,7 @@
 # problems with the newer kernel or lack certain things that make 
 # integration in the distro harder than needed.
 #
-%define package_conflicts kudzu <= 0.92, initscripts < 7.23, udev < 063-6, iptables < 1.3.2-1, ipw2200-firmware < 2.2 selinux-policy-targeted < 1.25.3-14
+%define package_conflicts kudzu < 1.2.5, initscripts < 7.23, udev < 063-6, iptables < 1.3.2-1, ipw2200-firmware < 2.4, selinux-policy-targeted < 1.25.3-14
 
 #
 # The ld.so.conf.d file we install uses syntax older ldconfig's don't grok.
@@ -65,15 +149,17 @@
 #
 %define kernel_prereq  fileutils, module-init-tools, initscripts >= 8.11.1-1, mkinitrd >= 4.2.21-1
 
-Name: kernel-xen
+Name: kernel
 Group: System Environment/Kernel
 License: GPLv2
 Version: %{rpmversion}
 Release: %{release}
-ExclusiveArch: %{all_x86}
+ExclusiveArch: noarch i686
+#ExclusiveArch: noarch %{all_x86} x86_64 ppc ppc64 ia64 sparc sparc64 ppc64iseries
 ExclusiveOS: Linux
-Provides: kernel = 2.6.13
+Provides: kernel = %{version}
 Provides: kernel-drm = 4.3.0
+Provides: kernel-%{_target_cpu} = %{rpmversion}-%{release}
 Prereq: %{kernel_prereq}
 Conflicts: %{kernel_dot_org_conflicts}
 Conflicts: %{package_conflicts}
@@ -92,84 +178,317 @@
 
 
 Source0: ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-%{kversion}.tar.bz2
-Source1: xen-20051109.tar.gz
-Source2: Config.mk
+
 Source10: COPYING.modules
+Source11: genkey
 
-Source31: kernel-%{kversion}-i686-hypervisor.config
-Source32: kernel-%{kversion}-i686-guest.config
+Source20: kernel-%{kversion}-i586.config
+Source21: kernel-%{kversion}-i686.config
+Source22: kernel-%{kversion}-i686-smp.config
+Source23: kernel-%{kversion}-x86_64.config
+Source24: kernel-%{kversion}-ppc64.config
+Source25: kernel-%{kversion}-ppc64iseries.config
+Source26: kernel-%{kversion}-s390.config
+Source27: kernel-%{kversion}-s390x.config
+Source28: kernel-%{kversion}-ppc.config
+Source29: kernel-%{kversion}-ppc-smp.config
+Source30: kernel-%{kversion}-ia64.config
+Source31: kernel-%{kversion}-i686-xen0.config
+Source32: kernel-%{kversion}-i686-xenU.config
+Source33: kernel-%{kversion}-i686-kdump.config
+#Source34: kernel-%{kversion}-sparc.config
+#Source35: kernel-%{kversion}-sparc64.config
+#Source36: kernel-%{kversion}-sparc64-smp.config
 
 #
 # Patches 0 through 100 are meant for core subsystem upgrades
 #
+Patch1: patch-2.6.15-rc4.bz2
+Patch2: patch-2.6.15-rc4-git1.bz2
+
[...2722 lines suppressed...]
+* Tue Jun 8 2004 Dave Jones <davej at redhat.com>
+- Update to 2.6.7rc3
+
+* Fri Jun 4 2004 Arjan van de Ven <arjanv at redhat.com>
+- fix the mlock-uses-rlimit patch
+
+* Wed Jun 2 2004 David Woodhouse <dwmw2 at redhat.com>
+- Add ppc64 (Mac G5)
+
+* Wed Jun 2 2004 Arjan van de Ven <arjanv at redhat.com>
+- add a forward port of the mlock-uses-rlimit patch
+- add NX support for x86 (Intel, Ingo)
+
+* Tue Jun 1 2004 Arjan van de Ven <arjanv at redhat.com>
+- refresh ext3 reservation patch
+
+* Sun May 30 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.7-rc2
+- set the ACPI OS name to "Microsoft Windows XP" for better compatibility
+
+* Thu May 27 2004 Pete Zaitcev <zaitcev at redhat.com>
+- Fix qeth and zfcp (s390 drivers): align qib by 256, embedded into qdio_irq.
+
+* Thu May 27 2004 Dave Jones <davej at redhat.com>
+- Fix the crashes on boot on Asus P4P800 boards. (#121819)
+
+* Wed May 26 2004 Dave Jones <davej at redhat.com>
+- Lots more updates to the SCSI whitelist for various
+  USB card readers. (#112778, among others..)
+
+* Wed May 26 2004 Arjan van de Ven <arjanv at redhat.com>
+- back out ehci suspend/resume patch, it breaks
+- add fix for 3c59x-meets-kudzu bug from Alan
+
+* Tue May 25 2004 Arjan van de Ven <arjanv at redhat.com>
+- try improving suspend/resume by restoring more PCI state
+- 2.6.7-rc1-bk1
+
+* Mon May 24 2004 Dave Jones <davej at redhat.com>
+- Add yet another multi-card reader to the whitelist (#85851)
+
+* Sun May 23 2004 Dave Jones <davej at redhat.com>
+- Add another multi-card reader to the whitelist (#124048)
+
+* Wed May 19 2004 Arjan van de Ven <arjanv at redhat.com>
+- put firewire race fix in (datacorruptor)
+
+* Tue May 18 2004 Dave Jones <davej at redhat.com>
+- Fix typo in ibmtr driver preventing compile (#123391)
+
+* Mon May 17 2004 Arjan van de Ven <arjanv at redhat.com>
+- update to 2.6.6-bk3
+- made kernel-source and kernel-doc noarch.rpm's since they are not
+  architecture specific.
+
+* Sat May 08 2004 Arjan van de Ven <arjanv at redhat.com>
+- fix non-booting on Transmeta cpus (Peter Anvin)
+- fix count leak in message queues
+
+* Fri May 07 2004 Arjan van de Ven <arjanv at redhat.com>
+- more ide cache flush work
+- patch from scsi-bk to fix sd refcounting
+
+* Thu May 06 2004 Arjan van de Ven <arjanv at redhat.com>
+- some more ide cache flush fixes 
+
+* Wed May 05 2004 Arjan van de Ven <arjanv at redhat.com>
+- fix bug 122504
+- convert b44 to ethtool ops (jgarzik)
+- make IDE do a cache-flush on shutdown (me/Alan)
+
+* Tue May 04 2004 Arjan van de Ven <arjanv at redhat.com>
+- work around i810/i830 DRM issue
+
+* Fri Apr 30 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.6-rc3-bk1
+- make amd64 boot again
+- fix vm86-vs-4g4g interaction (Ingo)
+
+* Thu Apr 22 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.6-rc2
+ 
+* Tue Apr 20 2004 Arjan van de Ven <arjanv at redhat.com>
+- add the ext3 online resize patch
 
-* Sat Oct 22 2005 Arjan van de Ven <arjanv at redhat.com>
-- update to latest mercurial tree; still has issues on my test box though
+* Mon Apr 19 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.6-rc1-bk3
+- add the objrmap vm from the -mm tree; it needs testing
+
+* Thu Apr 15 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.5-bk2
+- disable DISCONTIGMEM on ia64 for performance
+- fix sleep_on use in reiserfs (Chris Mason)
+
+* Tue Apr 13 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.5-mc4
+- reenable sg driver for scsi tape changers and such
+- the sk98lin driver oopses on module unload, preven that
+
+* Mon Apr 12 2004 Arjan van de Ven <arjanv at redhat.com>
+- fix "bad pmd" bug with patch from Ingo
+
+* Fri Apr 09 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.5-mc3
+- finish up the -mc2 merge
+- latest 4g/4g patch from Ingo
+- latest execshield patch from Ingo
+- fix a few framebuffer bugs
+
+* Thu Apr 08 2004 Arjan van de Ven <arjanv at redhat.com>
+- first attempt at a 2.6.5-mc2 merge
+
+* Thu Apr 08 2004 Dave Jones <davej at redhat.com>
+- Add in missing SiS AGP fix.
+
+* Tue Apr 06 2004 Dave Jones <davej at redhat.com>
+- More agpgart fixes.
+
+* Fri Apr 02 2004 Arjan van de Ven <arjanv at redhat.com>
+- fix another 4g/4g-vs-resume bug
+
+* Tue Mar 30 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.5-rc3
+- fix PCI posting bug in i830 DRM
+
+* Mon Mar 29 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.5-rc2-bk8
+
+* Mon Mar 29 2004 Dave Jones <davej at redhat.com>
+- Include latest agpgart fixes.
+
+* Thu Mar 25 2004 Arjan van de Ven <arjanv at redhat.com>
+- more DRM fixes
+- add the fsync patches from akpm
+
+* Tue Mar 23 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.5-rc2-bk3
+- fix direct userspace memory access in i830 drm driver
+
+* Mon Mar 22 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.5-rc2-bk2
+- some stackbloat reductions from Dave and me
+
+* Sat Mar 20 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.5-rc2
+
+* Tue Mar 16 2004 Dave Jones <davej at redhat.com>
+- 2.6.5-rc1
+
+* Mon Mar 15 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.4-bk3
+- fix oops in toshiba_acpi (Barry K. Nathan)
+
+* Sat Mar 13 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.4-bk2 merge 
+
+* Thu Mar 11 2004 Arjan van de Ven <arjanv at redhat.com>
+- renable sonypi driver that was off accidentally
+- 2.6.4-final 
+- fix the oops on alsa module unloads
+
+* Wed Mar 10 2004 Arjan van de Ven <arjanv at redhat.com>
+- add ppc64/iseries, ppc32 (powermac/ibook) and ia64 architectures
+- 2.6.4-rc3 
+
+* Tue Mar 09 2004 Arjan van de Ven <arjanv at redhat.com>
+- 2.6.4-rc2-bk5
+- fix nfs-vs-selinux issue
+- fix typo in URL as per #117849
+
+* Mon Mar 08 2004 Arjan van de Ven <arjanv at redhat.com>
+- fix race in lp.c (#117710)
+- 2.6.4-rc2-bk3
+- attempt to fix S3 suspend-to-ram with 4g/4g split
+
+* Sat Mar 06 2004 Arjan van de Ven <arjanv at redhat.com>
+- fix reiserfs
+- set HZ to 1000 again for some tests
+
+* Wed Feb 25 2004 Arjan van de Ven <arjanv at redhat.com>
+- merge back a bunch of fedora fixes
+- disable audit
+
+* Tue Feb 24 2004 Arjan van de Ven <arjanv at redhat.com>
+- audit bugfixes
+- update tux to a working version
+- 2.6.3-bk5 merge
+
+* Fri Feb 20 2004 Arjan van de Ven <arjanv at redhat.com>
+- re-add and enable the Auditing patch
+- switch several cpufreq modules to built in since detecting in userspace
+  which to use is unpleasant
 
-* Fri Oct 21 2005 Arjan van de Ven <arjanv at redhat.com>
-- start packaging a temporary Xen kernel rpm set
+* Thu Jul 03 2003 Arjan van de Ven <arjanv at redhat.com>
+- 2.6 start
 

linux-2.6-build-nonintconfig.patch:
 linux-2.6.14/scripts/kconfig/confdata.c |    8 +++-----
 linux-800/scripts/kconfig/Makefile      |    4 ++++
 linux-800/scripts/kconfig/conf.c        |   26 +++++++++++++++++++++++---
 3 files changed, 30 insertions(+), 8 deletions(-)

Index: linux-2.6-build-nonintconfig.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel-xen/devel/linux-2.6-build-nonintconfig.patch,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
--- linux-2.6-build-nonintconfig.patch	21 Oct 2005 17:43:32 -0000	1.1
+++ linux-2.6-build-nonintconfig.patch	2 Dec 2005 22:11:30 -0000	1.1.2.1
@@ -15,7 +15,7 @@
  
 +static int return_value = 0;
 +
- static void strip(signed char *str)
+ static void strip(char *str)
  {
  	char *p = str;
 @@ -93,6 +96,12 @@ static void conf_askvalue(struct symbol 
@@ -99,23 +99,52 @@
  .PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig
  
  randconfig: $(obj)/conf
---- linux-2.6.12/scripts/kconfig/confdata.c~	2005-06-22 13:17:13.000000000 -0400
-+++ linux-2.6.12/scripts/kconfig/confdata.c	2005-06-22 13:17:23.000000000 -0400
-@@ -129,7 +129,7 @@ int conf_read(const char *name)
+--- linux-2.6.14/scripts/kconfig/confdata.c~	2005-11-10 14:55:46.000000000 -0500
++++ linux-2.6.14/scripts/kconfig/confdata.c	2005-11-10 14:56:01.000000000 -0500
+@@ -149,7 +149,7 @@ int conf_read_simple(const char *name)
  				continue;
  			sym = sym_find(line + 9);
  			if (!sym) {
--				fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9);
-+				//fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9);
+-				conf_warning("trying to assign nonexistent symbol %s", line + 9);
++				//conf_warning("trying to assign nonexistent symbol %s", line + 9);
  				break;
- 			}
- 			switch (sym->type) {
-@@ -154,7 +154,7 @@ int conf_read(const char *name)
+ 			} else if (!(sym->flags & SYMBOL_NEW)) {
+ 				conf_warning("trying to reassign symbol %s", sym->name);
+@@ -179,7 +179,7 @@ int conf_read_simple(const char *name)
  				*p2 = 0;
  			sym = sym_find(line + 7);
  			if (!sym) {
--				fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
-+				//fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
+-				conf_warning("trying to assign nonexistent symbol %s", line + 7);
++				//conf_warning("trying to assign nonexistent symbol %s", line + 7);
+ 				break;
+ 			} else if (!(sym->flags & SYMBOL_NEW)) {
+ 				conf_warning("trying to reassign symbol %s", sym->name);
+--- linux-2.6.14/scripts/kconfig/confdata.c~	2005-11-15 23:51:37.000000000 -0500
++++ linux-2.6.14/scripts/kconfig/confdata.c	2005-11-15 23:52:50.000000000 -0500
+@@ -153,7 +153,6 @@ int conf_read_simple(const char *name)
+ 				break;
+ 			} else if (!(sym->flags & SYMBOL_NEW)) {
+ 				conf_warning("trying to reassign symbol %s", sym->name);
+-				break;
+ 			}
+ 			switch (sym->type) {
+ 			case S_BOOLEAN:
+@@ -183,7 +182,6 @@ int conf_read_simple(const char *name)
  				break;
+ 			} else if (!(sym->flags & SYMBOL_NEW)) {
+ 				conf_warning("trying to reassign symbol %s", sym->name);
+-				break;
  			}
  			switch (sym->type) {
+ 			case S_TRISTATE:
+--- linux-2.6.14/scripts/kconfig/confdata.c~	2005-11-16 00:06:16.000000000 -0500
++++ linux-2.6.14/scripts/kconfig/confdata.c	2005-11-16 00:06:40.000000000 -0500
+@@ -254,7 +254,7 @@ int conf_read_simple(const char *name)
+ 					cs->flags |= SYMBOL_NEW;
+ 				} else
+ 					cs->user.val = sym;
+-				break;
++				//break;
+ 			}
+ 			cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
+ 		}


Index: sources
===================================================================
RCS file: /cvs/dist/rpms/kernel-xen/devel/sources,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -r1.3 -r1.3.2.1
--- sources	9 Nov 2005 22:43:07 -0000	1.3
+++ sources	2 Dec 2005 22:11:31 -0000	1.3.2.1
@@ -1,2 +1,4 @@
-c5d2a1b62e1dad502c871bba267337d5  linux-2.6.12.tar.bz2
-1863fcae4b328ea4d7da4d927038d98d  xen-20051109.tar.gz
+66d02cbd723876c6d69846a067875a22  linux-2.6.14.tar.bz2
+952cab5831dbe772be689621df7b2746  patch-2.6.15-rc4-git1.bz2
+71ab943f14e8406e8dde1f65ab6b6c30  patch-2.6.15-rc4.bz2
+c2ad141034c9b1b5564d04cb82067cbf  xen-20051202.tar.gz




More information about the fedora-cvs-commits mailing list