diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	Wed Nov 26 21:03:44 2003
+++ b/arch/ia64/Kconfig	Wed Nov 26 21:03:44 2003
@@ -621,6 +621,33 @@
 	  keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
 	  unless you really know what this hack does.
 
+config IA64_EARLY_PRINTK
+	bool "Early printk support"
+	depends on DEBUG_KERNEL && !IA64_GENERIC
+	help
+	  Selecting this option uses the VGA screen or serial console for
+	  printk() output before the consoles are initialised.  It is useful
+	  for debugging problems early in the boot process, but only if you
+	  have a suitable VGA/serial console attached.  If you're unsure,
+	  select N.
+
+config IA64_EARLY_PRINTK_UART
+	bool "Early printk on MMIO serial port"
+	depends on IA64_EARLY_PRINTK
+
+config IA64_EARLY_PRINTK_UART_BASE
+	hex "UART MMIO base address"
+	depends on IA64_EARLY_PRINTK_UART
+	default "ff5e0000"
+
+config IA64_EARLY_PRINTK_VGA
+	bool "Early printk on VGA"
+	depends on IA64_EARLY_PRINTK
+
+config IA64_EARLY_PRINTK_SGI_SN
+	bool "Early printk on SGI SN serial console"
+	depends on IA64_EARLY_PRINTK && (IA64_GENERIC || IA64_SGI_SN2)
+
 config DEBUG_SLAB
 	bool "Debug memory allocations"
 	depends on DEBUG_KERNEL
diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c
--- a/drivers/acpi/tables.c	Wed Nov 26 21:03:43 2003
+++ b/drivers/acpi/tables.c	Wed Nov 26 21:03:43 2003
@@ -262,10 +262,17 @@
 
 	/* Map the DSDT header via the pointer in the FADT */
 	if (id == ACPI_DSDT) {
-		struct acpi_table_fadt *fadt = (struct acpi_table_fadt *) *header;
+		struct fadt_descriptor_rev2 *fadt = (struct fadt_descriptor_rev2 *) *header;
+
+		if (fadt->revision == 3 && fadt->Xdsdt) {
+			*header = (void *) __acpi_map_table(fadt->Xdsdt,
+					sizeof(struct acpi_table_header));
+		} else if (fadt->V1_dsdt) {
+			*header = (void *) __acpi_map_table(fadt->V1_dsdt,
+					sizeof(struct acpi_table_header));
+		} else
+			*header = 0;
 
-		*header = (void *) __acpi_map_table(fadt->dsdt_addr,
-				sizeof(struct acpi_table_header));
 		if (!*header) {
 			printk(KERN_WARNING PREFIX "Unable to map DSDT\n");
 			return -ENODEV;
diff -Nru a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
--- a/drivers/media/radio/Makefile	Wed Nov 26 21:03:43 2003
+++ b/drivers/media/radio/Makefile	Wed Nov 26 21:03:43 2003
@@ -2,6 +2,8 @@
 # Makefile for the kernel character device drivers.
 #
 
+obj-y		:= dummy.o
+
 miropcm20-objs	:= miropcm20-rds-core.o miropcm20-radio.o
 
 obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
diff -Nru a/drivers/media/radio/dummy.c b/drivers/media/radio/dummy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/radio/dummy.c	Wed Nov 26 21:03:44 2003
@@ -0,0 +1 @@
+/* just so the linker knows what kind of object files it's deadling with... */
diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile
--- a/drivers/media/video/Makefile	Wed Nov 26 21:03:43 2003
+++ b/drivers/media/video/Makefile	Wed Nov 26 21:03:43 2003
@@ -7,6 +7,7 @@
 zoran-objs      :=	zr36120.o zr36120_i2c.o zr36120_mem.o
 zr36067-objs	:=	zoran_procfs.o zoran_device.o \
 			zoran_driver.o zoran_card.o
+obj-y		:=	dummy.o
 
 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
 
diff -Nru a/drivers/media/video/dummy.c b/drivers/media/video/dummy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/dummy.c	Wed Nov 26 21:03:44 2003
@@ -0,0 +1 @@
+/* just so the linker knows what kind of object files it's deadling with... */
diff -Nru a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
--- a/drivers/net/tulip/media.c	Wed Nov 26 21:03:43 2003
+++ b/drivers/net/tulip/media.c	Wed Nov 26 21:03:43 2003
@@ -278,6 +278,10 @@
 				for (i = 0; i < init_length; i++)
 					outl(init_sequence[i], ioaddr + CSR12);
 			}
+
+			(void) inl(ioaddr + CSR6); /* flush CSR12 writes */
+			udelay(500);		/* Give MII time to recover */
+
 			tmp_info = get_u16(&misc_info[1]);
 			if (tmp_info)
 				tp->advertising[phy_num] = tmp_info | 1;
diff -Nru a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
--- a/drivers/serial/serial_core.c	Wed Nov 26 21:03:43 2003
+++ b/drivers/serial/serial_core.c	Wed Nov 26 21:03:43 2003
@@ -1862,6 +1862,9 @@
 	if (flow == 'r')
 		termios.c_cflag |= CRTSCTS;
 
+	if (!port->ops)
+		return 0;
+
 	port->ops->set_termios(port, &termios, NULL);
 	co->cflag = termios.c_cflag;
 
diff -Nru a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
--- a/fs/proc/task_mmu.c	Wed Nov 26 21:03:43 2003
+++ b/fs/proc/task_mmu.c	Wed Nov 26 21:03:43 2003
@@ -1,6 +1,7 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/seq_file.h>
+#include <asm/elf.h>
 #include <asm/uaccess.h>
 
 char *task_mem(struct mm_struct *mm, char *buffer)
@@ -75,6 +76,23 @@
 	return size;
 }
 
+#ifdef AT_SYSINFO_EHDR
+
+char gate_dso_path[256] = "";
+static struct vm_area_struct gate_vmarea = {
+	/* Do _not_ mark this area as readable, cuz not the entire range may be readable
+	   (e.g., due to execute-only pages or holes) and the tools that read
+	   /proc/PID/maps should read the interesting bits from the gate-DSO file
+	   instead.  */
+	.vm_start = FIXADDR_USER_START,
+	.vm_end = FIXADDR_USER_END
+};
+
+# define gate_map()	&gate_vmarea
+#else
+# define gate_map()	NULL
+#endif
+
 static int show_map(struct seq_file *m, void *v)
 {
 	struct vm_area_struct *map = v;
@@ -100,12 +118,15 @@
 			map->vm_pgoff << PAGE_SHIFT,
 			MAJOR(dev), MINOR(dev), ino, &len);
 
-	if (map->vm_file) {
+	if (map->vm_file || map == gate_map()) {
 		len = 25 + sizeof(void*) * 6 - len;
 		if (len < 1)
 			len = 1;
 		seq_printf(m, "%*c", len, ' ');
-		seq_path(m, file->f_vfsmnt, file->f_dentry, " \t\n\\");
+		if (map == gate_map())
+			seq_printf (m, "%s", gate_dso_path);
+		else
+			seq_path(m, file->f_vfsmnt, file->f_dentry, " \t\n\\");
 	}
 	seq_putc(m, '\n');
 	return 0;
@@ -128,6 +149,8 @@
 	if (!map) {
 		up_read(&mm->mmap_sem);
 		mmput(mm);
+		if (l == -1)
+			map = gate_map();
 	}
 	return map;
 }
@@ -135,7 +158,7 @@
 static void m_stop(struct seq_file *m, void *v)
 {
 	struct vm_area_struct *map = v;
-	if (map) {
+	if (map && map != gate_map()) {
 		struct mm_struct *mm = map->vm_mm;
 		up_read(&mm->mmap_sem);
 		mmput(mm);
@@ -149,6 +172,8 @@
 	if (map->vm_next)
 		return map->vm_next;
 	m_stop(m, v);
+	if (map != gate_map())
+		return gate_map();
 	return NULL;
 }
 
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h	Wed Nov 26 21:03:44 2003
+++ b/include/linux/module.h	Wed Nov 26 21:03:44 2003
@@ -60,10 +60,11 @@
 #define __module_cat(a,b) ___module_cat(a,b)
 #define __MODULE_INFO(tag, name, info)					  \
 static const char __module_cat(name,__LINE__)[]				  \
+  __attribute_used__							  \
   __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
 
-#define MODULE_GENERIC_TABLE(gtype,name)			\
-extern const struct gtype##_id __mod_##gtype##_table		\
+#define MODULE_GENERIC_TABLE(gtype,name)		\
+extern const struct gtype##_id __mod_##gtype##_table	\
   __attribute__ ((unused, alias(__stringify(name))))
 
 #define THIS_MODULE (&__this_module)
@@ -142,6 +143,7 @@
 #define __CRC_SYMBOL(sym, sec)					\
 	extern void *__crc_##sym __attribute__((weak));		\
 	static const unsigned long __kcrctab_##sym		\
+	__attribute_used__					\
 	__attribute__((section("__kcrctab" sec), unused))	\
 	= (unsigned long) &__crc_##sym;
 #else
@@ -155,6 +157,7 @@
 	__attribute__((section("__ksymtab_strings")))		\
 	= MODULE_SYMBOL_PREFIX #sym;                    	\
 	static const struct kernel_symbol __ksymtab_##sym	\
+	__attribute_used__					\
 	__attribute__((section("__ksymtab" sec), unused))	\
 	= { (unsigned long)&sym, __kstrtab_##sym }
 
diff -Nru a/include/linux/moduleparam.h b/include/linux/moduleparam.h
--- a/include/linux/moduleparam.h	Wed Nov 26 21:03:43 2003
+++ b/include/linux/moduleparam.h	Wed Nov 26 21:03:43 2003
@@ -52,6 +52,7 @@
 #define __module_param_call(prefix, name, set, get, arg, perm)		\
 	static char __param_str_##name[] __initdata = prefix #name;	\
 	static struct kernel_param const __param_##name			\
+	__attribute_used__						\
     __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
 	= { __param_str_##name, perm, set, get, arg }
 
diff -Nru a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
--- a/include/linux/nfs_fs.h	Wed Nov 26 21:03:43 2003
+++ b/include/linux/nfs_fs.h	Wed Nov 26 21:03:43 2003
@@ -403,7 +403,7 @@
 nfs_size_to_loff_t(__u64 size)
 {
 	loff_t maxsz = (((loff_t) ULONG_MAX) << PAGE_CACHE_SHIFT) + PAGE_CACHE_SIZE - 1;
-	if (size > maxsz)
+	if (size > (__u64) maxsz)
 		return maxsz;
 	return (loff_t) size;
 }
diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h	Wed Nov 26 21:03:43 2003
+++ b/include/linux/sysctl.h	Wed Nov 26 21:03:43 2003
@@ -127,6 +127,7 @@
 	KERN_PANIC_ON_OOPS=57,  /* int: whether we will panic on an oops */
 	KERN_HPPA_PWRSW=58,	/* int: hppa soft-power enable */
 	KERN_HPPA_UNALIGNED=59,	/* int: hppa unaligned-trap enable */
+	KERN_GATE_DSO=60,	/* string: path to gate DSO file */
 };
 
 
diff -Nru a/kernel/printk.c b/kernel/printk.c
--- a/kernel/printk.c	Wed Nov 26 21:03:44 2003
+++ b/kernel/printk.c	Wed Nov 26 21:03:44 2003
@@ -361,6 +361,12 @@
 			__call_console_drivers(start, end);
 		}
 	}
+#ifdef CONFIG_IA64_EARLY_PRINTK
+	if (!console_drivers) {
+		void early_printk (const char *str, size_t len);
+		early_printk(&LOG_BUF(start), end - start);
+	}
+#endif
 }
 
 /*
@@ -678,7 +684,11 @@
 		 * for us.
 		 */
 		spin_lock_irqsave(&logbuf_lock, flags);
+#ifdef CONFIG_IA64_EARLY_PRINTK
+		con_start = log_end;
+#else
 		con_start = log_start;
+#endif
 		spin_unlock_irqrestore(&logbuf_lock, flags);
 	}
 	release_console_sem();
@@ -731,3 +741,117 @@
 		tty->driver->write(tty, 0, msg, strlen(msg));
 	return;
 }
+
+#ifdef CONFIG_IA64_EARLY_PRINTK
+
+#include <asm/io.h>
+
+# ifdef CONFIG_IA64_EARLY_PRINTK_VGA
+
+
+#define VGABASE		((char *)0xc0000000000b8000)
+#define VGALINES	24
+#define VGACOLS		80
+
+static int current_ypos = VGALINES, current_xpos = 0;
+
+static void
+early_printk_vga (const char *str, size_t len)
+{
+	char c;
+	int  i, k, j;
+
+	while (len-- > 0) {
+		c = *str++;
+		if (current_ypos >= VGALINES) {
+			/* scroll 1 line up */
+			for (k = 1, j = 0; k < VGALINES; k++, j++) {
+				for (i = 0; i < VGACOLS; i++) {
+					writew(readw(VGABASE + 2*(VGACOLS*k + i)),
+					       VGABASE + 2*(VGACOLS*j + i));
+				}
+			}
+			for (i = 0; i < VGACOLS; i++) {
+				writew(0x720, VGABASE + 2*(VGACOLS*j + i));
+			}
+			current_ypos = VGALINES-1;
+		}
+		if (c == '\n') {
+			current_xpos = 0;
+			current_ypos++;
+		} else if (c != '\r')  {
+			writew(((0x7 << 8) | (unsigned short) c),
+			       VGABASE + 2*(VGACOLS*current_ypos + current_xpos++));
+			if (current_xpos >= VGACOLS) {
+				current_xpos = 0;
+				current_ypos++;
+			}
+		}
+	}
+}
+
+# endif /* CONFIG_IA64_EARLY_PRINTK_VGA */
+
+# ifdef CONFIG_IA64_EARLY_PRINTK_UART
+
+#include <linux/serial_reg.h>
+#include <asm/system.h>
+
+static void early_printk_uart(const char *str, size_t len)
+{
+	static char *uart = NULL;
+	unsigned long uart_base;
+	char c;
+
+	if (!uart) {
+		uart_base = 0;
+#  ifdef CONFIG_SERIAL_8250_HCDP
+		{
+			extern unsigned long hcdp_early_uart(void);
+			uart_base = hcdp_early_uart();
+		}
+#  endif
+#  if CONFIG_IA64_EARLY_PRINTK_UART_BASE
+		if (!uart_base)
+			uart_base = CONFIG_IA64_EARLY_PRINTK_UART_BASE;
+#  endif
+		if (!uart_base)
+			return;
+
+		uart = ioremap(uart_base, 64);
+		if (!uart)
+			return;
+	}
+
+	while (len-- > 0) {
+		c = *str++;
+		while ((readb(uart + UART_LSR) & UART_LSR_TEMT) == 0)
+			cpu_relax(); /* spin */
+
+		writeb(c, uart + UART_TX);
+
+		if (c == '\n')
+			writeb('\r', uart + UART_TX);
+	}
+}
+
+# endif /* CONFIG_IA64_EARLY_PRINTK_UART */
+
+#ifdef CONFIG_IA64_EARLY_PRINTK_SGI_SN
+extern int early_printk_sn_sal(const char *str, int len);
+#endif
+
+void early_printk(const char *str, size_t len)
+{
+#ifdef CONFIG_IA64_EARLY_PRINTK_UART
+	early_printk_uart(str, len);
+#endif
+#ifdef CONFIG_IA64_EARLY_PRINTK_VGA
+	early_printk_vga(str, len);
+#endif
+#ifdef CONFIG_IA64_EARLY_PRINTK_SGI_SN
+ 	early_printk_sn_sal(str, len);
+#endif
+}
+
+#endif /* CONFIG_IA64_EARLY_PRINTK */
diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
--- a/kernel/sysctl.c	Wed Nov 26 21:03:43 2003
+++ b/kernel/sysctl.c	Wed Nov 26 21:03:43 2003
@@ -37,6 +37,7 @@
 #include <linux/hugetlb.h>
 #include <linux/security.h>
 #include <linux/initrd.h>
+#include <asm/elf.h>
 #include <asm/uaccess.h>
 
 #ifdef CONFIG_ROOT_NFS
@@ -65,6 +66,9 @@
 static int maxolduid = 65535;
 static int minolduid;
 
+#ifdef AT_SYSINFO_EHDR
+extern char gate_dso_path[];
+#endif
 #ifdef CONFIG_KMOD
 extern char modprobe_path[];
 #endif
@@ -389,6 +393,17 @@
 		.ctl_name	= KERN_HOTPLUG,
 		.procname	= "hotplug",
 		.data		= &hotplug_path,
+		.maxlen		= 256,
+		.mode		= 0644,
+		.proc_handler	= &proc_dostring,
+		.strategy	= &sysctl_string,
+	},
+#endif
+#ifdef AT_SYSINFO_EHDR
+	{
+		.ctl_name	= KERN_GATE_DSO,
+		.procname	= "gate_dso",
+		.data		= &gate_dso_path,
 		.maxlen		= 256,
 		.mode		= 0644,
 		.proc_handler	= &proc_dostring,
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Wed Nov 26 21:03:43 2003
+++ b/mm/memory.c	Wed Nov 26 21:03:43 2003
@@ -121,8 +121,10 @@
 	}
 	pmd = pmd_offset(dir, 0);
 	pgd_clear(dir);
-	for (j = 0; j < PTRS_PER_PMD ; j++)
+	for (j = 0; j < PTRS_PER_PMD ; j++) {
+		prefetchw(pmd + j + PREFETCH_STRIDE/sizeof(*pmd));
 		free_one_pmd(tlb, pmd+j);
+	}
 	pmd_free_tlb(tlb, pmd);
 }
 
