Whamcloud - gitweb
merge b_devel into HEAD, which will become 0.7.3
authorphil <phil>
Fri, 25 Jul 2003 18:10:53 +0000 (18:10 +0000)
committerphil <phil>
Fri, 25 Jul 2003 18:10:53 +0000 (18:10 +0000)
 - dozens and dozens of fixes for working with 2.6 kernels
 - new 2.4 kernel APIs
 - uncountable bug fixes

155 files changed:
lnet/tests/Makefile.mk [new file with mode: 0644]
lnet/utils/Makefile.mk [new file with mode: 0644]
lustre/include/linux/lustre_commit_confd.h [new file with mode: 0644]
lustre/include/linux/lustre_log.h [new file with mode: 0644]
lustre/include/linux/lustre_mgmt.h [new file with mode: 0644]
lustre/include/linux/obd_filter.h [deleted file]
lustre/kernel_patches/kernel_configs/kgdb-vmware-2.5.73 [new file with mode: 0644]
lustre/kernel_patches/patches/2.6.0-test1-mm2.patch [new file with mode: 0644]
lustre/kernel_patches/patches/dump_netdev.patch [new file with mode: 0644]
lustre/kernel_patches/patches/ext3-2.4.18-fixes.patch [deleted file]
lustre/kernel_patches/patches/ext3-2.5-noread.patch [deleted file]
lustre/kernel_patches/patches/ext3-2.5.63.patch [deleted file]
lustre/kernel_patches/patches/ext3-error-export.patch [new file with mode: 0644]
lustre/kernel_patches/patches/ext3-map_inode_page.patch [new file with mode: 0644]
lustre/kernel_patches/patches/ext3-map_inode_page_2.4.18.patch [new file with mode: 0644]
lustre/kernel_patches/patches/ext3-noread-inode.patch [new file with mode: 0644]
lustre/kernel_patches/patches/ext3-san-jdike-2.5.73.patch [moved from lustre/kernel_patches/patches/extN-san.patch with 78% similarity]
lustre/kernel_patches/patches/ext3-truncate_blocks-chaos.patch.patch [deleted file]
lustre/kernel_patches/patches/ext3_delete_thread_2.4.20_chaos.patch [new file with mode: 0644]
lustre/kernel_patches/patches/extN-delete_thread.patch [deleted file]
lustre/kernel_patches/patches/extN-iget-debug.patch [deleted file]
lustre/kernel_patches/patches/gpl_header-chaos-2.4.20.patch [new file with mode: 0644]
lustre/kernel_patches/patches/inode-protection-from-pdflush.patch [new file with mode: 0644]
lustre/kernel_patches/patches/invalidate_show_2.4.20_chaos.patch [new file with mode: 0644]
lustre/kernel_patches/patches/iopen-2.5.73.patch [new file with mode: 0644]
lustre/kernel_patches/patches/jbd-transno-cb.patch [deleted file]
lustre/kernel_patches/patches/kexec-2.5.73-full.patch [new file with mode: 0644]
lustre/kernel_patches/patches/kexec-2.6.0-full.patch [new file with mode: 0644]
lustre/kernel_patches/patches/kgdb-ga-2.5.73.patch [new file with mode: 0644]
lustre/kernel_patches/patches/kgdb-ga-docco-fixes-2.5.73.patch [new file with mode: 0644]
lustre/kernel_patches/patches/kgdb-use-ggdb-2.5.73.patch [new file with mode: 0644]
lustre/kernel_patches/patches/lkcd-cvs-2.5.69.patch [new file with mode: 0644]
lustre/kernel_patches/patches/lkcd-kernel-changes-2.5.73.patch [new file with mode: 0644]
lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test1.patch [new file with mode: 0644]
lustre/kernel_patches/patches/lustre-2.5.63.patch [deleted file]
lustre/kernel_patches/patches/lustre_build.patch [new file with mode: 0644]
lustre/kernel_patches/patches/netconsole_sysrq.patch [deleted file]
lustre/kernel_patches/patches/qla2xxx-v8.00.00b1-2.5.73.patch [new file with mode: 0644]
lustre/kernel_patches/patches/tcp_zero_copy_2.4.20_chaos.patch [new file with mode: 0644]
lustre/kernel_patches/patches/tg3_netconsole.patch [deleted file]
lustre/kernel_patches/patches/uml-patch-2.4.20-6.patch [moved from lustre/kernel_patches/patches/uml-patch-2.4.20-4.patch with 93% similarity]
lustre/kernel_patches/patches/uml_compile_fixes.patch [deleted file]
lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch [moved from lustre/kernel_patches/patches/vfs_intent-2.4.18-18.patch with 64% similarity]
lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch [new file with mode: 0644]
lustre/kernel_patches/patches/vfs_intent_2.4.20_chaos.patch [new file with mode: 0644]
lustre/kernel_patches/patches/vfs_intent_2.5.72_rev1.patch [new file with mode: 0644]
lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch [new file with mode: 0644]
lustre/kernel_patches/patches/vfs_mntcwd_2.5.72_rev1.patch [new file with mode: 0644]
lustre/kernel_patches/patches/vfs_nointent_2.5.69_rev1.patch [new file with mode: 0644]
lustre/kernel_patches/patches/vfs_races_2.5.72_rev1.patch [new file with mode: 0644]
lustre/kernel_patches/pc/2.6.0-test1-mm2.pc [new file with mode: 0644]
lustre/kernel_patches/pc/dump_netdev.pc [new file with mode: 0644]
lustre/kernel_patches/pc/ext3-2.4.18-fixes.pc [deleted file]
lustre/kernel_patches/pc/ext3-2.5.63.pc [deleted file]
lustre/kernel_patches/pc/ext3-error-export.pc [new file with mode: 0644]
lustre/kernel_patches/pc/ext3-map_inode_page.pc [new file with mode: 0644]
lustre/kernel_patches/pc/ext3-map_inode_page_2.4.18.pc [new file with mode: 0644]
lustre/kernel_patches/pc/ext3-noread-inode.pc [moved from lustre/kernel_patches/pc/ext3-2.5-noread.pc with 100% similarity]
lustre/kernel_patches/pc/ext3-san-jdike-2.5.73.pc [moved from lustre/kernel_patches/pc/extN-san.pc with 100% similarity]
lustre/kernel_patches/pc/ext3-truncate_blocks-chaos.patch.pc [deleted file]
lustre/kernel_patches/pc/ext3_delete_thread_2.4.20_chaos.pc [moved from lustre/kernel_patches/pc/extN-delete_thread.pc with 68% similarity]
lustre/kernel_patches/pc/extN-iget-debug.pc [deleted file]
lustre/kernel_patches/pc/gpl_header-chaos-2.4.20.pc [new file with mode: 0644]
lustre/kernel_patches/pc/inode-protection-from-pdflush.pc [new file with mode: 0644]
lustre/kernel_patches/pc/inode-unhash_2.5.75.pc [new file with mode: 0644]
lustre/kernel_patches/pc/invalidate_show_2.4.20_chaos.pc [new file with mode: 0644]
lustre/kernel_patches/pc/iopen-2.5.73.pc [new file with mode: 0644]
lustre/kernel_patches/pc/jbd-transno-cb.pc [deleted file]
lustre/kernel_patches/pc/kexec-2.5.73-full.pc [new file with mode: 0644]
lustre/kernel_patches/pc/kexec-2.6.0-full.pc [new file with mode: 0644]
lustre/kernel_patches/pc/kgdb-ga-2.5.73.pc [new file with mode: 0644]
lustre/kernel_patches/pc/kgdb-ga-docco-fixes-2.5.73.pc [new file with mode: 0644]
lustre/kernel_patches/pc/kgdb-use-ggdb-2.5.73.pc [new file with mode: 0644]
lustre/kernel_patches/pc/lkcd-cvs-2.5.69.pc [new file with mode: 0644]
lustre/kernel_patches/pc/lkcd-kernel-changes-2.5.73.pc [new file with mode: 0644]
lustre/kernel_patches/pc/lkcd-kernel-changes-2.6.0-test1.pc [new file with mode: 0644]
lustre/kernel_patches/pc/lustre_build.pc [new file with mode: 0644]
lustre/kernel_patches/pc/netconsole_sysrq.pc [deleted file]
lustre/kernel_patches/pc/qla2xxx-v8.00.00b1-2.5.73.pc [new file with mode: 0644]
lustre/kernel_patches/pc/tcp_zero_copy_2.4.20_chaos.pc [new file with mode: 0644]
lustre/kernel_patches/pc/tg3_netconsole.pc [deleted file]
lustre/kernel_patches/pc/uml-patch-2.4.20-6.pc [moved from lustre/kernel_patches/pc/uml-patch-2.4.20-4.pc with 99% similarity]
lustre/kernel_patches/pc/uml_compile_fixes.pc [deleted file]
lustre/kernel_patches/pc/vfs_intent-2.4.18-18-chaos65.pc [moved from lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc with 74% similarity]
lustre/kernel_patches/pc/vfs_intent-2.4.20-hp.pc [new file with mode: 0644]
lustre/kernel_patches/pc/vfs_intent_2.4.20_chaos.pc [new file with mode: 0644]
lustre/kernel_patches/pc/vfs_intent_2.5.72_rev1.pc [moved from lustre/kernel_patches/pc/lustre-2.5.63.pc with 63% similarity]
lustre/kernel_patches/pc/vfs_intent_2.6.0-test1.pc [new file with mode: 0644]
lustre/kernel_patches/pc/vfs_mntcwd_2.5.72_rev1.pc [new file with mode: 0644]
lustre/kernel_patches/pc/vfs_nointent_2.5.69_rev1.pc [new file with mode: 0644]
lustre/kernel_patches/pc/vfs_races_2.5.72_rev1.pc [new file with mode: 0644]
lustre/kernel_patches/series/chaos-2.4.18 [moved from lustre/kernel_patches/series/chaos with 82% similarity]
lustre/kernel_patches/series/chaos-2.4.20 [new file with mode: 0644]
lustre/kernel_patches/series/kgdb-2.5.73 [new file with mode: 0644]
lustre/kernel_patches/series/kgdb_2.6.0_test1 [new file with mode: 0644]
lustre/kernel_patches/series/rh-2.4.18-18 [deleted file]
lustre/kernel_patches/series/vanilla-2.5 [deleted file]
lustre/kernel_patches/txt/ext3-map_inode_page.txt [moved from lustre/kernel_patches/txt/uml_compile_fixes.txt with 100% similarity]
lustre/kernel_patches/txt/ext3-map_inode_page_2.4.18.txt [new file with mode: 0644]
lustre/ldlm/Makefile.mk [new file with mode: 0644]
lustre/llite/llite_lib.c [new file with mode: 0644]
lustre/lov/lov_internal.h [new file with mode: 0644]
lustre/mdc/Makefile.mk [new file with mode: 0644]
lustre/mds/commit_confd.c [new file with mode: 0644]
lustre/obdclass/obdo.c [new file with mode: 0644]
lustre/obdclass/recov_log.c [new file with mode: 0644]
lustre/obdfilter/filter_internal.h [new file with mode: 0644]
lustre/obdfilter/filter_io.c [new file with mode: 0644]
lustre/obdfilter/filter_log.c [new file with mode: 0644]
lustre/obdfilter/filter_san.c [new file with mode: 0644]
lustre/ost/Makefile.mk [new file with mode: 0644]
lustre/portals/tests/Makefile.mk [new file with mode: 0644]
lustre/portals/utils/Makefile.mk [new file with mode: 0644]
lustre/ptlrpc/Makefile.mk [new file with mode: 0644]
lustre/ptlrpc/recov_thread.c [new file with mode: 0644]
lustre/tests/client-echo.cfg [deleted file]
lustre/tests/client-mount.cfg [deleted file]
lustre/tests/client-mount2.cfg [deleted file]
lustre/tests/common.sh [deleted file]
lustre/tests/elan-client.cfg [deleted file]
lustre/tests/elan-server.cfg [deleted file]
lustre/tests/ext2_10000.gz [deleted file]
lustre/tests/ext2_25000.gz [deleted file]
lustre/tests/ext3_10000.gz [deleted file]
lustre/tests/fs.sh [deleted file]
lustre/tests/intent-test.sh [deleted file]
lustre/tests/intent-test2.sh [deleted file]
lustre/tests/ldlm.cfg [deleted file]
lustre/tests/llcleanup.sh [deleted file]
lustre/tests/lldlm.sh [deleted file]
lustre/tests/llext3.sh [deleted file]
lustre/tests/llmodules.sh [deleted file]
lustre/tests/llmount-client.sh [deleted file]
lustre/tests/llmount-server.sh [deleted file]
lustre/tests/llrext3.sh [deleted file]
lustre/tests/llrsetup.sh [deleted file]
lustre/tests/llsetup.sh [deleted file]
lustre/tests/llsimple.sh [deleted file]
lustre/tests/lustre.cfg [deleted file]
lustre/tests/mdcreq.sh [deleted file]
lustre/tests/mdcreqcleanup.sh [deleted file]
lustre/tests/mds.cfg [deleted file]
lustre/tests/modules.cfg [deleted file]
lustre/tests/net-client.cfg [deleted file]
lustre/tests/net-local.cfg [deleted file]
lustre/tests/net-server.cfg [deleted file]
lustre/tests/obddisk.cfg [deleted file]
lustre/tests/obdecho.cfg [deleted file]
lustre/tests/obdfilter.cfg [deleted file]
lustre/tests/ostreq.sh [deleted file]
lustre/tests/replay-single.sh [new file with mode: 0755]
lustre/tests/runfailure-client-mds-recover.sh [deleted file]
lustre/tests/small_write.c [new file with mode: 0644]
lustre/tests/snaprun.sh [deleted file]
lustre/tests/trivial.sh [deleted file]

diff --git a/lnet/tests/Makefile.mk b/lnet/tests/Makefile.mk
new file mode 100644 (file)
index 0000000..751c0a0
--- /dev/null
@@ -0,0 +1,9 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+include $(src)/../Kernelenv
+
+obj-y += ping_cli.o
+obj-y += ping_srv.o
diff --git a/lnet/utils/Makefile.mk b/lnet/utils/Makefile.mk
new file mode 100644 (file)
index 0000000..cbbe6d5
--- /dev/null
@@ -0,0 +1,6 @@
+include $(src)/../Kernelenv
+
+host-progs := acceptor ptlctl
+always := $(host-progs)
+
+ptlctl-objs := ptlctl.o $(PTLCTLOBJS)
diff --git a/lustre/include/linux/lustre_commit_confd.h b/lustre/include/linux/lustre_commit_confd.h
new file mode 100644 (file)
index 0000000..980e6ce
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <info@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Structures relating to the log commit thread.
+ */
+
+#ifndef _LUSTRE_COMMIT_CONFD_H
+#define _LUSTRE_COMMIT_CONFD_H
+
+#include <linux/lustre_log.h>
+
+struct llog_commit_data {
+        struct list_head           llcd_list;  /* free or pending struct list */
+        struct obd_import         *llcd_import;
+        struct llog_commit_master *llcd_lcm;
+        int                        llcd_tries; /* number of tries to send */
+        int                        llcd_cookiebytes;
+        struct llog_cookie         llcd_cookies[0];
+};
+
+struct llog_commit_master {
+        struct list_head        lcm_thread_busy;  /* list of busy daemons */
+        struct list_head        lcm_thread_idle;  /* list of idle daemons */
+        spinlock_t              lcm_thread_lock;  /* protects thread_list */
+        atomic_t                lcm_thread_numidle;/* number of idle threads */
+        atomic_t                lcm_thread_total; /* total number of threads */
+        int                     lcm_thread_max;   /* <= num_osts normally */
+
+        int                     lcm_flags;
+        wait_queue_head_t       lcm_waitq;
+
+        struct list_head        lcm_llcd_pending; /* llog_commit_data to send */
+        struct list_head        lcm_llcd_resend;  /* try to resend this data */
+        struct list_head        lcm_llcd_free;    /* free llog_commit_data */
+        spinlock_t              lcm_llcd_lock;    /* protects llcd_free */
+        atomic_t                lcm_llcd_numfree; /* items on llcd_free */
+        int                     lcm_llcd_minfree; /* min free on llcd_free */
+        int                     lcm_llcd_maxfree; /* max free on llcd_free */
+};
+
+#define LLOG_LCM_FL_EXIT        0x01
+#define LLOG_LCM_FL_EXIT_FORCE  0x02
+
+/* the thread data that collects local commits and makes rpc's */
+struct llog_commit_daemon {
+        struct list_head           lcd_lcm_list;  /* list of daemon threads */
+        struct list_head           lcd_llcd_list; /* list of pending RPCs */
+        struct llog_commit_master *lcd_lcm;       /* pointer back to parent */
+};
+
+/* ptlrpc/recov_thread.c */
+int llog_start_commit_thread(void);
+struct llog_commit_data *llcd_grab(void);
+void llcd_send(struct llog_commit_data *llcd);
+
+#endif /* _LUSTRE_COMMIT_CONFD_H */
diff --git a/lustre/include/linux/lustre_log.h b/lustre/include/linux/lustre_log.h
new file mode 100644 (file)
index 0000000..2f21583
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <info@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Generic infrastructure for managing a collection of logs.
+ *
+ * These logs are used for:
+ *
+ * - orphan recovery: OST adds record on create
+ * - mtime/size consistency: the OST adds a record on first write
+ * - open/unlinked objects: OST adds a record on destroy
+ *
+ * - mds unlink log: the MDS adds an entry upon delete
+ *
+ * - raid1 replication log between OST's
+ * - MDS replication logs
+ */
+
+#ifndef _LUSTRE_LOG_H
+#define _LUSTRE_LOG_H
+
+#include <linux/lustre_idl.h>
+
+struct obd_trans_info;
+struct obd_device;
+struct lov_stripe_md;
+
+/* In-memory descriptor for a log object or log catalog */
+struct llog_handle {
+        struct list_head        lgh_list;
+        struct llog_cookie      lgh_cookie;
+        struct semaphore        lgh_lock;
+        struct obd_device      *lgh_obd;
+        void                   *lgh_hdr;
+        struct file            *lgh_file;
+        struct obd_uuid        *lgh_tgtuuid;
+        struct llog_handle     *lgh_current;
+        struct llog_handle     *(*lgh_log_create)(struct obd_device *obd);
+        struct llog_handle     *(*lgh_log_open)(struct obd_device *obd,
+                                                struct llog_cookie *logcookie);
+        int                     (*lgh_log_close)(struct llog_handle *cathandle,
+                                                 struct llog_handle *loghandle);
+        int                     lgh_index;
+};
+
+extern int llog_add_record(struct llog_handle *cathandle,
+                           struct llog_trans_hdr *rec,
+                           struct llog_cookie *logcookies);
+
+extern int llog_cancel_records(struct llog_handle *cathandle, int count,
+                               struct llog_cookie *cookies);
+
+extern struct llog_handle *llog_alloc_handle(void);
+extern void llog_free_handle(struct llog_handle *handle);
+extern int llog_init_catalog(struct llog_handle *cathandle,
+                             struct obd_uuid *tgtuuid);
+extern int llog_delete_log(struct llog_handle *cathandle,
+                           struct llog_handle *loghandle);
+extern int llog_close_log(struct llog_handle *cathandle,
+                          struct llog_handle *loghandle);
+extern struct llog_handle *llog_new_log(struct llog_handle *cathandle,
+                                        struct obd_uuid *tgtuuid);
+
+#endif
+
diff --git a/lustre/include/linux/lustre_mgmt.h b/lustre/include/linux/lustre_mgmt.h
new file mode 100644 (file)
index 0000000..91a8113
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2001  Cluster File Systems, Inc.
+ *
+ * This code is issued under the GNU General Public License.
+ * See the file COPYING in this distribution
+ */
+
+#ifndef LUSTRE_MGMT_H
+#define LUSTRE_MGMT_H
+
+#define LUSTRE_MGMTCLI_NAME "mgmt_cli"
+
+/* For the convenience and type-safety of inter_module_getters. */
+
+struct obd_device;
+struct obd_uuid;
+
+/*
+ * The caller is responsible for ensuring that relevant_uuid -- if non-NULL --
+ * points to valid memory until deregister is called.  If relevant_uuid is NULL,
+ * all management events will be propagated to the registrant.  Notice that
+ * deregister doesn't take a relevant_uuid-matching parameter; I should probably
+ * fix that at some point.
+ */
+typedef int (*mgmtcli_register_for_events_t)(struct obd_device *mgmt_obd,
+                                             struct obd_device *notify_obd,
+                                             struct obd_uuid *relevant_uuid);
+
+typedef int (*mgmtcli_deregister_for_events_t)(struct obd_device *mgmt_obd,
+                                               struct obd_device *notify_obd);
+
+#endif /* LUSTRE_MGMT_H */
diff --git a/lustre/include/linux/obd_filter.h b/lustre/include/linux/obd_filter.h
deleted file mode 100644 (file)
index 3d8188a..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2002 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef _OBD_FILTER_H
-#define _OBD_FILTER_H
-
-#ifdef __KERNEL__
-#include <linux/spinlock.h>
-#endif
-#include <linux/lustre_handles.h>
-
-#ifndef OBD_FILTER_DEVICENAME
-#define OBD_FILTER_DEVICENAME "obdfilter"
-#endif
-
-#define FILTER_LR_SERVER_SIZE    512
-
-#define FILTER_LR_CLIENT_START   8192
-#define FILTER_LR_CLIENT_SIZE    128
-
-#define FILTER_SUBDIR_COUNT      32            /* set to zero for no subdirs */
-
-#define FILTER_MOUNT_RECOV 2
-#define FILTER_RECOVERY_TIMEOUT (obd_timeout * 5 * HZ / 2) /* *waves hands* */
-
-/* Data stored per server at the head of the last_rcvd file.  In le32 order. */
-struct filter_server_data {
-        __u8  fsd_uuid[37];        /* server UUID */
-        __u8  fsd_uuid_padding[3]; /* unused */
-        __u64 fsd_last_objid;      /* last created object ID */
-        __u64 fsd_last_rcvd;       /* last completed transaction ID */
-        __u64 fsd_mount_count;     /* FILTER incarnation number */
-        __u32 fsd_feature_compat;  /* compatible feature flags */
-        __u32 fsd_feature_rocompat;/* read-only compatible feature flags */
-        __u32 fsd_feature_incompat;/* incompatible feature flags */
-        __u32 fsd_server_size;     /* size of server data area */
-        __u32 fsd_client_start;    /* start of per-client data area */
-        __u16 fsd_client_size;     /* size of per-client data area */
-        __u16 fsd_subdir_count;    /* number of subdirectories for objects */
-        __u8  fsd_padding[FILTER_LR_SERVER_SIZE - 88];
-};
-
-/* Data stored per client in the last_rcvd file.  In le32 order. */
-struct filter_client_data {
-        __u8  fcd_uuid[37];        /* client UUID */
-        __u8  fcd_uuid_padding[3]; /* unused */
-        __u64 fcd_last_rcvd;       /* last completed transaction ID */
-        __u64 fcd_mount_count;     /* FILTER incarnation number */
-        __u64 fcd_last_xid;        /* client RPC xid for the last transaction */
-        __u8  fcd_padding[FILTER_LR_CLIENT_SIZE - 64];
-};
-
-#ifndef OBD_FILTER_SAN_DEVICENAME
-#define OBD_FILTER_SAN_DEVICENAME "sanobdfilter"
-#endif
-
-/* In-memory access to client data from OST struct */
-struct filter_export_data {
-        struct list_head  fed_open_head; /* files to close on disconnect */
-        spinlock_t        fed_lock;      /* protects fed_open_head */
-        struct filter_client_data  *fed_fcd;
-        loff_t            fed_lr_off;
-        int               fed_lr_idx;
-};
-
-/* file data for open files on OST */
-struct filter_file_data {
-        struct portals_handle ffd_handle;
-        atomic_t              ffd_refcount;
-        struct list_head      ffd_export_list; /* export open list - fed_lock */
-        struct file          *ffd_file;         /* file handle */
-};
-
-struct filter_dentry_data {
-        obd_id                  fdd_objid;
-        __u32                   fdd_magic;
-        atomic_t                fdd_open_count;
-        int                     fdd_flags;
-};
-
-#define FILTER_DENTRY_MAGIC 0x9efba101
-#define FILTER_FLAG_DESTROY 0x0001      /* destroy dentry on last file close */
-
-
-#endif
diff --git a/lustre/kernel_patches/kernel_configs/kgdb-vmware-2.5.73 b/lustre/kernel_patches/kernel_configs/kgdb-vmware-2.5.73
new file mode 100644 (file)
index 0000000..4033739
--- /dev/null
@@ -0,0 +1,908 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_GENERIC_ISA_DMA=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_EMBEDDED is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+CONFIG_MPENTIUMIII=y
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MELAN is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+# CONFIG_X86_GENERIC is not set
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=5
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=16
+# CONFIG_PREEMPT is not set
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_TSC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_X86_MCE_P4THERMAL=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+# CONFIG_MICROCODE is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+CONFIG_EDD=y
+CONFIG_NOHIGHMEM=y
+# CONFIG_HIGHMEM4G is not set
+# CONFIG_HIGHMEM64G is not set
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Power management options (ACPI, APM)
+#
+# CONFIG_PM is not set
+
+#
+# ACPI Support
+#
+# CONFIG_ACPI is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_PCI_NAMES=y
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+# CONFIG_YENTA is not set
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Generic Driver Options
+#
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+CONFIG_PNP_NAMES=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_LBD=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_TASKFILE_IO=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_BLK_DEV_CMD640=y
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDE_TCQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+CONFIG_BLK_DEV_RZ1000=y
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_REPORT_LUNS=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_IPV6 is not set
+# CONFIG_XFRM_USER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_LLC is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# CONFIG_EEPRO100_PIO is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices (depends on LLC=y)
+#
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# I2C Hardware Sensors Mainboard support
+#
+
+#
+# I2C Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+CONFIG_AGP=y
+# CONFIG_AGP_ALI is not set
+# CONFIG_AGP_AMD is not set
+# CONFIG_AGP_AMD_8151 is not set
+# CONFIG_AGP_INTEL is not set
+# CONFIG_AGP_NVIDIA is not set
+# CONFIG_AGP_SIS is not set
+# CONFIG_AGP_SWORKS is not set
+# CONFIG_AGP_VIA is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_MWAVE is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_GSS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+CONFIG_LUSTRE_FS=y
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+CONFIG_VIDEO_SELECT=y
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+
+#
+# Kernel hacking
+#
+# CONFIG_CRASH_DUMP is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_IOVIRT is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_KALLSYMS=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_KGDB=y
+# CONFIG_KGDB_9600BAUD is not set
+# CONFIG_KGDB_19200BAUD is not set
+# CONFIG_KGDB_38400BAUD is not set
+# CONFIG_KGDB_57600BAUD is not set
+CONFIG_KGDB_115200BAUD=y
+CONFIG_KGDB_PORT=0x3f8
+CONFIG_KGDB_IRQ=4
+CONFIG_DEBUG_INFO=y
+# CONFIG_KGDB_MORE is not set
+CONFIG_NO_KGDB_CPUS=16
+# CONFIG_KGDB_TS is not set
+# CONFIG_STACK_OVERFLOW_TEST is not set
+CONFIG_KGDB_CONSOLE=y
+CONFIG_KGDB_SYSRQ=y
+CONFIG_FRAME_POINTER=y
+CONFIG_X86_EXTRA_IRQS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+
+#
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
diff --git a/lustre/kernel_patches/patches/2.6.0-test1-mm2.patch b/lustre/kernel_patches/patches/2.6.0-test1-mm2.patch
new file mode 100644 (file)
index 0000000..9f476e0
--- /dev/null
@@ -0,0 +1,179799 @@
+--- linux-2.6.0-test1/arch/alpha/kernel/irq.c  2003-06-14 12:18:29.000000000 -0700
++++ 25/arch/alpha/kernel/irq.c 2003-07-19 17:03:49.000000000 -0700
+@@ -601,7 +601,7 @@ handle_irq(int irq, struct pt_regs * reg
+       if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
+               irq_err_count++;
+               illegal_count++;
+-              printk(KERN_CRIT "device_interrupt: illegal interrupt %d\n",
++              printk(KERN_CRIT "device_interrupt: invalid interrupt %d\n",
+                      irq);
+               return;
+       }
+--- linux-2.6.0-test1/arch/alpha/kernel/smp.c  2003-06-14 12:18:05.000000000 -0700
++++ 25/arch/alpha/kernel/smp.c 2003-07-19 17:04:06.000000000 -0700
+@@ -71,7 +71,7 @@ static int smp_secondary_alive __initdat
+ /* Which cpus ids came online.  */
+ unsigned long cpu_present_mask;
+-volatile unsigned long cpu_online_map;
++cpumask_t cpu_online_map;
+ /* cpus reported in the hwrpb */
+ static unsigned long hwrpb_cpu_present_mask __initdata = 0;
+@@ -132,7 +132,7 @@ smp_callin(void)
+ {
+       int cpuid = hard_smp_processor_id();
+-      if (test_and_set_bit(cpuid, &cpu_online_map)) {
++      if (cpu_test_and_set(cpuid, cpu_online_map)) {
+               printk("??, cpu 0x%x already present??\n", cpuid);
+               BUG();
+       }
+@@ -575,8 +575,8 @@ smp_prepare_boot_cpu(void)
+       /*
+        * Mark the boot cpu (current cpu) as both present and online
+        */ 
+-      set_bit(smp_processor_id(), &cpu_present_mask);
+-      set_bit(smp_processor_id(), &cpu_online_map);
++      cpu_set(smp_processor_id(), cpu_present_mask);
++      cpu_set(smp_processor_id(), cpu_online_map);
+ }
+ int __devinit
+--- linux-2.6.0-test1/arch/alpha/mm/init.c     2003-06-14 12:18:33.000000000 -0700
++++ 25/arch/alpha/mm/init.c    2003-07-19 17:03:49.000000000 -0700
+@@ -20,9 +20,6 @@
+ #include <linux/init.h>
+ #include <linux/bootmem.h> /* max_low_pfn */
+ #include <linux/vmalloc.h>
+-#ifdef CONFIG_BLK_DEV_INITRD
+-#include <linux/blk.h>
+-#endif
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+--- linux-2.6.0-test1/arch/alpha/mm/remap.c    2003-06-14 12:17:56.000000000 -0700
++++ 25/arch/alpha/mm/remap.c   2003-07-19 17:07:16.000000000 -0700
+@@ -73,7 +73,7 @@ __alpha_remap_area_pages(unsigned long a
+       spin_lock(&init_mm.page_table_lock);
+       do {
+               pmd_t *pmd;
+-              pmd = pmd_alloc(&init_mm, dir, address);
++              pmd = pmd_alloc_kernel(&init_mm, dir, address);
+               error = -ENOMEM;
+               if (!pmd)
+                       break;
+--- linux-2.6.0-test1/arch/arm26/kernel/setup.c        2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/arm26/kernel/setup.c       2003-07-19 17:03:49.000000000 -0700
+@@ -14,7 +14,7 @@
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+ #include <linux/utsname.h>
+-#include <linux/blk.h>
++#include <linux/blkdev.h>
+ #include <linux/console.h>
+ #include <linux/bootmem.h>
+ #include <linux/seq_file.h>
+--- linux-2.6.0-test1/arch/arm26/mm/init.c     2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/arm26/mm/init.c    2003-07-19 17:03:49.000000000 -0700
+@@ -22,7 +22,7 @@
+ #include <linux/init.h>
+ #include <linux/initrd.h>
+ #include <linux/bootmem.h>
+-#include <linux/blk.h>
++#include <linux/blkdev.h>
+ #include <asm/segment.h>
+ #include <asm/mach-types.h>
+--- linux-2.6.0-test1/arch/arm26/mm/mm-memc.c  2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/arm26/mm/mm-memc.c 2003-07-19 17:07:16.000000000 -0700
+@@ -79,7 +79,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+               goto no_pgd;
+       /*
+-       * This lock is here just to satisfy pmd_alloc and pte_lock
++       * This lock is here just to satisfy pmd_alloc_kernel() and pte_lock
+          * FIXME: I bet we could avoid taking it pretty much altogether
+        */
+       spin_lock(&mm->page_table_lock);
+@@ -88,7 +88,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+        * On ARM, first page must always be allocated since it contains
+        * the machine vectors.
+        */
+-      new_pmd = pmd_alloc(mm, new_pgd, 0);
++      new_pmd = pmd_alloc_kernel(mm, new_pgd, 0);
+       if (!new_pmd)
+               goto no_pmd;
+--- linux-2.6.0-test1/arch/arm/mach-arc/mm.c   2003-06-14 12:18:08.000000000 -0700
++++ 25/arch/arm/mach-arc/mm.c  2003-07-19 17:07:16.000000000 -0700
+@@ -66,7 +66,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+               goto no_pgd;
+       /*
+-       * This lock is here just to satisfy pmd_alloc and pte_lock
++       * This lock is here just to satisfy pmd_alloc_map() and pte_lock
+        */
+       spin_lock(&mm->page_table_lock);
+@@ -74,13 +74,15 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+        * On ARM, first page must always be allocated since it contains
+        * the machine vectors.
+        */
+-      new_pmd = pmd_alloc(mm, new_pgd, 0);
++      new_pmd = pmd_alloc_map(mm, new_pgd, 0);
+       if (!new_pmd)
+               goto no_pmd;
+-      new_pte = pte_alloc_map(mm, new_pmd, 0);
+-      if (!new_pte)
++      new_pte = pte_alloc_map(mm, new_pgd, &new_pmd, 0);
++      if (!new_pte) {
++              pmd_unmap(new_pmd);
+               goto no_pte;
++      }
+       init_pgd = pgd_offset_k(0);
+       init_pmd = pmd_offset(init_pgd, 0);
+@@ -88,6 +90,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+       set_pte(new_pte, *init_pte);
+       pte_unmap_nested(init_pte);
+       pte_unmap(new_pte);
++      pmd_unmap(new_pmd);
+       /*
+        * most of the page table entries are zeroed
+--- linux-2.6.0-test1/arch/arm/mach-clps711x/autcpu12.c        2003-06-14 12:18:04.000000000 -0700
++++ 25/arch/arm/mach-clps711x/autcpu12.c       2003-07-19 17:03:49.000000000 -0700
+@@ -21,7 +21,6 @@
+ #include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/string.h>
+-#include <linux/blk.h>
+ #include <linux/mm.h>
+ #include <asm/hardware.h>
+--- linux-2.6.0-test1/arch/arm/mm/consistent.c 2003-06-14 12:18:29.000000000 -0700
++++ 25/arch/arm/mm/consistent.c        2003-07-19 17:07:16.000000000 -0700
+@@ -325,7 +325,7 @@ static int __init consistent_init(void)
+       do {
+               pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
+-              pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
++              pmd = pmd_alloc_kernel(&init_mm, pgd, CONSISTENT_BASE);
+               if (!pmd) {
+                       printk(KERN_ERR "consistent_init: out of pmd tables\n");
+                       return -ENOMEM;
+--- linux-2.6.0-test1/arch/arm/mm/ioremap.c    2003-06-14 12:18:24.000000000 -0700
++++ 25/arch/arm/mm/ioremap.c   2003-07-19 17:07:16.000000000 -0700
+@@ -95,7 +95,7 @@ static int remap_area_pages(unsigned lon
+       spin_lock(&init_mm.page_table_lock);
+       do {
+               pmd_t *pmd;
+-              pmd = pmd_alloc(&init_mm, dir, address);
++              pmd = pmd_alloc_kernel(&init_mm, dir, address);
+               error = -ENOMEM;
+               if (!pmd)
+                       break;
+--- linux-2.6.0-test1/arch/arm/mm/minicache.c  2003-06-14 12:18:25.000000000 -0700
++++ 25/arch/arm/mm/minicache.c 2003-07-19 17:07:16.000000000 -0700
+@@ -57,7 +57,7 @@ static int __init minicache_init(void)
+       pmd_t *pmd;
+       pgd = pgd_offset_k(minicache_address);
+-      pmd = pmd_alloc(&init_mm, pgd, minicache_address);
++      pmd = pmd_alloc_kernel(&init_mm, pgd, minicache_address);
+       if (!pmd)
+               BUG();
+       minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address);
+--- linux-2.6.0-test1/arch/arm/mm/mm-armv.c    2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/arm/mm/mm-armv.c   2003-07-19 17:07:16.000000000 -0700
+@@ -131,7 +131,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+       if (vectors_base() == 0) {
+               /*
+-               * This lock is here just to satisfy pmd_alloc and pte_lock
++               * This lock is here just to satisfy pmd_alloc_map() and pte_lock
+                */
+               spin_lock(&mm->page_table_lock);
+@@ -139,20 +139,22 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+                * On ARM, first page must always be allocated since it
+                * contains the machine vectors.
+                */
+-              new_pmd = pmd_alloc(mm, new_pgd, 0);
++              new_pmd = pmd_alloc_map(mm, new_pgd, 0);
+               if (!new_pmd)
+                       goto no_pmd;
+-              new_pte = pte_alloc_map(mm, new_pmd, 0);
+-              if (!new_pte)
++              new_pte = pte_alloc_map(mm, new_pgd, &new_pmd, 0);
++              if (!new_pte) {
++                      pmd_unmap(new_pmd);
+                       goto no_pte;
++              }
+               init_pmd = pmd_offset(init_pgd, 0);
+               init_pte = pte_offset_map_nested(init_pmd, 0);
+               set_pte(new_pte, *init_pte);
+               pte_unmap_nested(init_pte);
+               pte_unmap(new_pte);
+-
++              pmd_unmap(new_pmd);
+               spin_unlock(&mm->page_table_lock);
+       }
+--- linux-2.6.0-test1/arch/cris/mm/ioremap.c   2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/cris/mm/ioremap.c  2003-07-19 17:07:16.000000000 -0700
+@@ -78,7 +78,7 @@ static int remap_area_pages(unsigned lon
+       spin_lock(&init_mm.page_table_lock);
+       do {
+               pmd_t *pmd;
+-              pmd = pmd_alloc(&init_mm, dir, address);
++              pmd = pmd_alloc_kernel(&init_mm, dir, address);
+               error = -ENOMEM;
+               if (!pmd)
+                       break;
+--- linux-2.6.0-test1/arch/h8300/kernel/setup.c        2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/h8300/kernel/setup.c       2003-07-19 17:03:49.000000000 -0700
+@@ -35,7 +35,6 @@
+ #include <asm/irq.h>
+ #ifdef CONFIG_BLK_DEV_INITRD
+-#include <linux/blk.h>
+ #include <asm/pgtable.h>
+ #endif
+--- linux-2.6.0-test1/arch/h8300/mm/init.c     2003-06-14 12:18:21.000000000 -0700
++++ 25/arch/h8300/mm/init.c    2003-07-19 17:03:49.000000000 -0700
+@@ -23,9 +23,6 @@
+ #include <linux/errno.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
+-#ifdef CONFIG_BLK_DEV_RAM
+-#include <linux/blk.h>
+-#endif
+ #include <linux/ptrace.h>
+ #include <linux/mman.h>
+ #include <linux/mm.h>
+--- linux-2.6.0-test1/arch/i386/Kconfig        2003-07-13 21:44:34.000000000 -0700
++++ 25/arch/i386/Kconfig       2003-07-19 17:07:16.000000000 -0700
+@@ -438,9 +438,9 @@ config SMP
+         If you don't know what to do here, say N.
+ config NR_CPUS
+-      int "Maximum number of CPUs (2-32)"
++      int "Maximum number of CPUs (2-255)"
+       depends on SMP
+-      default "32"
++      default "8"
+       help
+         This allows you to specify the maximum number of CPUs which this
+         kernel will support.  The maximum supported value is 32 and the
+@@ -723,6 +723,16 @@ config HIGHPTE
+         low memory.  Setting this option will put user-space page table
+         entries in high memory.
++config HIGHPMD
++      bool "Allocate 2nd-level pagetables from highmem"
++      depends on HIGHMEM64G && HIGHPTE
++      help
++        The VM uses one lowmem-allocated pmd entry for each pagetable
++        page of physical memory allocated, and preallocates them all
++        for 12KB of per-process lowmem overhead. For systems with
++        extreme amounts of highmem, this cannot be tolerated. Setting
++        this option will put userspace 2nd-level pagetables in highmem.
++
+ config MATH_EMULATION
+       bool "Math emulation"
+       ---help---
+@@ -1347,6 +1357,15 @@ config DEBUG_PAGEALLOC
+         This results in a large slowdown, but helps to find certain types
+         of memory corruptions.
++config SPINLINE
++      bool "Spinlock inlining"
++      depends on DEBUG_KERNEL
++      help
++        This will change spinlocks from out of line to inline, making them
++        account cost to the callers in readprofile, rather than the lock
++        itself (as ".text.lock.filename"). This can be helpful for finding
++        the callers of locks.
++
+ config DEBUG_HIGHMEM
+       bool "Highmem debugging"
+       depends on DEBUG_KERNEL && HIGHMEM
+@@ -1354,20 +1373,207 @@ config DEBUG_HIGHMEM
+         This options enables addition error checking for high memory systems.
+         Disable for production systems.
++config LOCKMETER
++      bool "Kernel lock metering"
++      depends on SMP && !PREEMPT
++      help
++        Say Y to enable kernel lock metering, which adds overhead to SMP locks,
++        but allows you to see various statistics using the lockstat command.
++
+ config DEBUG_SPINLOCK_SLEEP
+       bool "Sleep-inside-spinlock checking"
+       help
+         If you say Y here, various routines which may sleep will become very
+         noisy if they are called with a spinlock held.        
++config KGDB
++      bool "Include kgdb kernel debugger"
++      depends on DEBUG_KERNEL
++      help  
++        If you say Y here, the system will be compiled with the debug
++        option (-g) and a debugging stub will be included in the
++        kernel.  This stub communicates with gdb on another (host)
++        computer via a serial port.  The host computer should have
++        access to the kernel binary file (vmlinux) and a serial port
++        that is connected to the target machine.  Gdb can be made to
++        configure the serial port or you can use stty and setserial to
++        do this. See the 'target' command in gdb. This option also
++        configures in the ability to request a breakpoint early in the
++        boot process.  To request the breakpoint just include 'kgdb'
++        as a boot option when booting the target machine.  The system
++        will then break as soon as it looks at the boot options.  This
++        option also installs a breakpoint in panic and sends any
++        kernel faults to the debugger. For more information see the
++        Documentation/i386/kgdb.txt file.
++
++choice
++      depends on KGDB
++      prompt "Debug serial port BAUD" 
++      default KGDB_115200BAUD
++      help  
++        Gdb and the kernel stub need to agree on the baud rate to be
++        used.  Some systems (x86 family at this writing) allow this to
++        be configured.
++
++config KGDB_9600BAUD
++      bool "9600"
++
++config KGDB_19200BAUD
++      bool "19200"
++
++config KGDB_38400BAUD
++      bool "38400"
++
++config KGDB_57600BAUD
++      bool "57600"
++
++config KGDB_115200BAUD
++      bool "115200"
++endchoice
++
++config KGDB_PORT
++      hex "hex I/O port address of the debug serial port"
++      depends on KGDB
++      default  3f8
++      help  
++        Some systems (x86 family at this writing) allow the port
++        address to be configured.  The number entered is assumed to be
++        hex, don't put 0x in front of it.  The standard address are:
++        COM1 3f8 , irq 4 and COM2 2f8 irq 3.  Setserial /dev/ttySx
++        will tell you what you have.  It is good to test the serial
++        connection with a live system before trying to debug.
++
++config KGDB_IRQ
++      int "IRQ of the debug serial port"
++      depends on KGDB
++      default 4
++      help  
++        This is the irq for the debug port.  If everything is working
++        correctly and the kernel has interrupts on a control C to the
++        port should cause a break into the kernel debug stub.
++
++config DEBUG_INFO
++      bool
++      default y
++
++config KGDB_MORE
++      bool "Add any additional compile options"
++      depends on KGDB
++      default n
++      help  
++        Saying yes here turns on the ability to enter additional
++        compile options.
++
++
++config KGDB_OPTIONS
++      depends on KGDB_MORE
++      string "Additional compile arguments"
++      default "-O1"
++      help  
++        This option allows you enter additional compile options for
++        the whole kernel compile.  Each platform will have a default
++        that seems right for it.  For example on PPC "-ggdb -O1", and
++        for i386 "-O1".  Note that by configuring KGDB "-g" is already
++        turned on.  In addition, on i386 platforms
++        "-fomit-frame-pointer" is deleted from the standard compile
++        options.
++
++config NO_KGDB_CPUS
++      int "Number of CPUs"
++      depends on KGDB && SMP
++      default NR_CPUS
++      help
++        
++        This option sets the number of cpus for kgdb ONLY.  It is used
++        to prune some internal structures so they look "nice" when
++        displayed with gdb.  This is to overcome possibly larger
++        numbers that may have been entered above.  Enter the real
++        number to get nice clean kgdb_info displays.
++
++config KGDB_TS
++      bool "Enable kgdb time stamp macros?"
++      depends on KGDB
++      default n
++      help      
++        Kgdb event macros allow you to instrument your code with calls
++        to the kgdb event recording function.  The event log may be
++        examined with gdb at a break point.  Turning on this
++        capability also allows you to choose how many events to
++        keep. Kgdb always keeps the lastest events.
++
++choice 
++      depends on KGDB_TS
++      prompt "Max number of time stamps to save?"
++      default KGDB_TS_128
++
++config KGDB_TS_64
++      bool "64"
++
++config KGDB_TS_128
++      bool "128"
++
++config KGDB_TS_256
++      bool "256"
++
++config KGDB_TS_512
++      bool "512"
++
++config KGDB_TS_1024
++      bool "1024"
++
++endchoice
++
++config STACK_OVERFLOW_TEST
++      bool "Turn on kernel stack overflow testing?"
++      depends on KGDB
++      default n
++      help  
++        This option enables code in the front line interrupt handlers
++        to check for kernel stack overflow on interrupts and system
++        calls.  This is part of the kgdb code on x86 systems.
++
++config KGDB_CONSOLE
++      bool "Enable serial console thru kgdb port"
++      depends on KGDB
++      default n
++      help
++        This option enables the command line "console=kgdb" option.
++        When the system is booted with this option in the command line
++        all kernel printk output is sent to gdb (as well as to other
++        consoles).  For this to work gdb must be connected.  For this
++        reason, this command line option will generate a breakpoint if
++        gdb has not yet connected.  After the gdb continue command is
++        given all pent up console output will be printed by gdb on the
++        host machine.  Neither this option, nor KGDB require the
++        serial driver to be configured.
++
++config KGDB_SYSRQ
++      bool "Turn on SysRq 'G' command to do a break?"
++      depends on KGDB
++      default y
++      help
++        This option includes an option in the SysRq code that allows
++        you to enter SysRq G which generates a breakpoint to the KGDB
++        stub.  This will work if the keyboard is alive and can
++        interrupt the system.  Because of constraints on when the
++        serial port interrupt can be enabled, this code may allow you
++        to interrupt the system before the serial port control C is
++        available.  Just say yes here.
++
+ config FRAME_POINTER
+       bool "Compile the kernel with frame pointers"
++      default KGDB
+       help
+         If you say Y here the resulting kernel image will be slightly larger
+         and slower, but it will give very useful debugging information.
+         If you don't debug the kernel, you can say N, but we may not be able
+         to solve problems without frame pointers.
++config MAGIC_SYSRQ
++      bool
++      depends on KGDB_SYSRQ
++      default y
++
+ config X86_EXTRA_IRQS
+       bool
+       depends on X86_LOCAL_APIC || X86_VOYAGER
+--- linux-2.6.0-test1/arch/i386/kernel/apic.c  2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/i386/kernel/apic.c 2003-07-19 17:04:06.000000000 -0700
+@@ -1137,7 +1137,7 @@ int __init APIC_init_uniprocessor (void)
+       connect_bsp_APIC();
+-      phys_cpu_present_map = 1 << boot_cpu_physical_apicid;
++      phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
+       setup_local_APIC();
+--- linux-2.6.0-test1/arch/i386/kernel/apm.c   2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/i386/kernel/apm.c  2003-07-19 17:04:06.000000000 -0700
+@@ -508,16 +508,16 @@ static void apm_error(char *str, int err
+  
+ #ifdef CONFIG_SMP
+-static unsigned long apm_save_cpus(void)
++static cpumask_t apm_save_cpus(void)
+ {
+-      unsigned long x = current->cpus_allowed;
++      cpumask_t x = current->cpus_allowed;
+       /* Some bioses don't like being called from CPU != 0 */
+-      set_cpus_allowed(current, 1UL << 0);
++      set_cpus_allowed(current, cpumask_of_cpu(0));
+       BUG_ON(smp_processor_id() != 0);
+       return x;
+ }
+-static inline void apm_restore_cpus(unsigned long mask)
++static inline void apm_restore_cpus(cpumask_t mask)
+ {
+       set_cpus_allowed(current, mask);
+ }
+@@ -528,7 +528,7 @@ static inline void apm_restore_cpus(unsi
+  *    No CPU lockdown needed on a uniprocessor
+  */
+  
+-#define apm_save_cpus()       0
++#define apm_save_cpus()               (current->cpus_allowed)
+ #define apm_restore_cpus(x)   (void)(x)
+ #endif
+@@ -593,7 +593,7 @@ static u8 apm_bios_call(u32 func, u32 eb
+ {
+       APM_DECL_SEGS
+       unsigned long           flags;
+-      unsigned long           cpus;
++      cpumask_t               cpus;
+       int                     cpu;
+       struct desc_struct      save_desc_40;
+@@ -635,7 +635,7 @@ static u8 apm_bios_call_simple(u32 func,
+       u8                      error;
+       APM_DECL_SEGS
+       unsigned long           flags;
+-      unsigned long           cpus;
++      cpumask_t               cpus;
+       int                     cpu;
+       struct desc_struct      save_desc_40;
+@@ -913,7 +913,7 @@ static void apm_power_off(void)
+        */
+ #ifdef CONFIG_SMP
+       /* Some bioses don't like being called from CPU != 0 */
+-      set_cpus_allowed(current, 1UL << 0);
++      set_cpus_allowed(current, cpumask_of_cpu(0));
+       BUG_ON(smp_processor_id() != 0);
+ #endif
+       if (apm_info.realmode_power_off)
+@@ -1704,7 +1704,7 @@ static int apm(void *unused)
+        * Some bioses don't like being called from CPU != 0.
+        * Method suggested by Ingo Molnar.
+        */
+-      set_cpus_allowed(current, 1UL << 0);
++      set_cpus_allowed(current, cpumask_of_cpu(0));
+       BUG_ON(smp_processor_id() != 0);
+ #endif
+--- linux-2.6.0-test1/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c       2003-06-14 12:18:33.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c      2003-07-19 17:04:06.000000000 -0700
+@@ -53,10 +53,9 @@ static int stock_freq;
+ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
+ {
+       u32 l, h;
+-      unsigned long cpus_allowed;
++      cpumask_t cpus_allowed, affected_cpu_map;
+       struct cpufreq_freqs freqs;
+       int hyperthreading = 0;
+-      int affected_cpu_map = 0;
+       int sibling = 0;
+       if (!cpu_online(cpu) || (newstate > DC_DISABLE) || 
+@@ -67,16 +66,16 @@ static int cpufreq_p4_setdc(unsigned int
+       cpus_allowed = current->cpus_allowed;
+       /* only run on CPU to be set, or on its sibling */
+-      affected_cpu_map = 1 << cpu;
++       affected_cpu_map = cpumask_of_cpu(cpu);
+ #ifdef CONFIG_X86_HT
+       hyperthreading = ((cpu_has_ht) && (smp_num_siblings == 2));
+       if (hyperthreading) {
+               sibling = cpu_sibling_map[cpu];
+-              affected_cpu_map |= (1 << sibling);
++                cpu_set(sibling, affected_cpu_map);
+       }
+ #endif
+       set_cpus_allowed(current, affected_cpu_map);
+-      BUG_ON(!(affected_cpu_map & (1 << smp_processor_id())));
++        BUG_ON(!cpu_isset(smp_processor_id(), affected_cpu_map));
+       /* get current state */
+       rdmsr(MSR_IA32_THERM_CONTROL, l, h);
+--- linux-2.6.0-test1/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c        2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c       2003-07-19 17:05:02.000000000 -0700
+@@ -156,14 +156,15 @@ static struct cpufreq_frequency_table op
+ };
+ #undef OP
+-#define CPU(max)      \
+-      { "Intel(R) Pentium(R) M processor " #max "MHz", (max)*1000, op_##max }
++#define _CPU(max, name)       \
++      { "Intel(R) Pentium(R) M processor " name "MHz", (max)*1000, op_##max }
++#define CPU(max)      _CPU(max, #max)
+ /* CPU models, their operating frequency range, and freq/voltage
+    operating points */
+ static const struct cpu_model models[] = 
+ {
+-      CPU( 900),
++       _CPU( 900, " 900"),
+       CPU(1100),
+       CPU(1200),
+       CPU(1300),
+--- linux-2.6.0-test1/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c     2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c    2003-07-19 17:08:59.000000000 -0700
+@@ -77,15 +77,17 @@ static void speedstep_set_state (unsigne
+       u8                      value;
+       unsigned long           flags;
+       struct cpufreq_freqs    freqs;
++      int                     newfreq;
+       if (!speedstep_chipset_dev || (state > 0x1))
+               return;
+       freqs.old = speedstep_get_processor_frequency(speedstep_processor);
+-      freqs.new = speedstep_freqs[SPEEDSTEP_LOW].frequency;
++      freqs.new = speedstep_freqs[state].frequency;
+       freqs.cpu = 0; /* speedstep.c is UP only driver */
+       
+-      if (notify)
++      /* make sure we've initialized before calling notify */
++      if (notify && (freqs.new != 0))
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       /* get PMBASE */
+@@ -136,13 +138,16 @@ static void speedstep_set_state (unsigne
+       dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
++      /* freqs.new may not be set yet - need local copy */
++      newfreq = speedstep_get_processor_frequency(speedstep_processor);
+       if (state == (value & 0x1)) {
+-              dprintk (KERN_INFO "cpufreq: change to %u MHz succeeded\n", (freqs.new / 1000));
++              dprintk (KERN_INFO "cpufreq: change to %u MHz succeeded\n", (newfreq / 1000));
+       } else {
+               printk (KERN_ERR "cpufreq: change failed - I/O error\n");
+       }
+-      if (notify)
++      /* Make sure we're initialized before calling notify */
++      if (notify && (freqs.new != 0))
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       return;
+@@ -295,7 +300,7 @@ static int speedstep_cpu_init(struct cpu
+               return -EIO;
+       dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", 
+-              (speed == speedstep_low_freq) ? "low" : "high",
++              (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
+               (speed / 1000));
+       /* cpuinfo and default policy values */
+--- linux-2.6.0-test1/arch/i386/kernel/cpuid.c 2003-06-14 12:17:55.000000000 -0700
++++ 25/arch/i386/kernel/cpuid.c        2003-07-19 17:04:06.000000000 -0700
+@@ -136,7 +136,7 @@ static int cpuid_open(struct inode *inod
+   int cpu = minor(file->f_dentry->d_inode->i_rdev);
+   struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+-  if ( !(cpu_online_map & (1UL << cpu)) )
++  if (!cpu_online(cpu))
+     return -ENXIO;            /* No such CPU */
+   if ( c->cpuid_level < 0 )
+     return -EIO;              /* CPUID not supported */
+--- linux-2.6.0-test1/arch/i386/kernel/cpu/mtrr/cyrix.c        2003-06-14 12:18:22.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mtrr/cyrix.c       2003-07-19 17:03:49.000000000 -0700
+@@ -330,16 +330,16 @@ cyrix_arr_init(void)
+       set_mtrr_done(&ctxt);   /* flush cache and disable MAPEN */
+       if (ccrc[5])
+-              printk("mtrr: ARR usage was not enabled, enabled manually\n");
++              printk(KERN_INFO "mtrr: ARR usage was not enabled, enabled manually\n");
+       if (ccrc[3])
+-              printk("mtrr: ARR3 cannot be changed\n");
++              printk(KERN_INFO "mtrr: ARR3 cannot be changed\n");
+ /*
+     if ( ccrc[1] & 0x80) printk ("mtrr: SMM memory access through ARR3 disabled\n");
+     if ( ccrc[1] & 0x04) printk ("mtrr: SMM memory access disabled\n");
+     if ( ccrc[1] & 0x02) printk ("mtrr: SMM mode disabled\n");
+ */
+       if (ccrc[6])
+-              printk("mtrr: ARR3 was write protected, unprotected\n");
++              printk(KERN_INFO "mtrr: ARR3 was write protected, unprotected\n");
+ }
+ static struct mtrr_ops cyrix_mtrr_ops = {
+--- linux-2.6.0-test1/arch/i386/kernel/cpu/mtrr/main.c 2003-06-26 22:07:22.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mtrr/main.c        2003-07-19 17:04:57.000000000 -0700
+@@ -64,7 +64,7 @@ __initdata char *mtrr_if_name[] = {
+ static void set_mtrr(unsigned int reg, unsigned long base,
+                    unsigned long size, mtrr_type type);
+-static unsigned int arr3_protected;
++extern int arr3_protected;
+ void set_mtrr_ops(struct mtrr_ops * ops)
+ {
+@@ -75,23 +75,25 @@ void set_mtrr_ops(struct mtrr_ops * ops)
+ /*  Returns non-zero if we have the write-combining memory type  */
+ static int have_wrcomb(void)
+ {
+-      struct pci_dev *dev = NULL;
+-
+-      /* WTF is this?
+-       * Someone, please shoot me.
+-       */
+-
+-      /* ServerWorks LE chipsets have problems with write-combining 
+-         Don't allow it and leave room for other chipsets to be tagged */
+-
++      struct pci_dev *dev;
++      
+       if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
+-              if ((dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
+-                  (dev->device == PCI_DEVICE_ID_SERVERWORKS_LE)) {
+-                      printk(KERN_INFO
+-                             "mtrr: Serverworks LE detected. Write-combining disabled.\n");
++              /* ServerWorks LE chipsets have problems with write-combining 
++                 Don't allow it and leave room for other chipsets to be tagged */
++              if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
++                  dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
++                      printk(KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n");
+                       return 0;
+               }
+-      }
++              /* Intel 450NX errata # 23. Non ascending cachline evictions to
++                 write combining memory may resulting in data corruption */
++              if (dev->vendor == PCI_VENDOR_ID_INTEL &&
++                  dev->device == PCI_DEVICE_ID_INTEL_82451NX)
++              {
++                      printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
++                      return 0;
++              }
++      }               
+       return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0);
+ }
+@@ -121,7 +123,7 @@ static void init_table(void)
+       max = num_var_ranges;
+       if ((usage_table = kmalloc(max * sizeof *usage_table, GFP_KERNEL))
+           == NULL) {
+-              printk("mtrr: could not allocate\n");
++              printk(KERN_ERR "mtrr: could not allocate\n");
+               return;
+       }
+       for (i = 0; i < max; i++)
+@@ -310,7 +312,7 @@ int mtrr_add_page(unsigned long base, un
+               return error;
+       if (type >= MTRR_NUM_TYPES) {
+-              printk("mtrr: type: %u illegal\n", type);
++              printk(KERN_WARNING "mtrr: type: %u invalid\n", type);
+               return -EINVAL;
+       }
+@@ -322,7 +324,7 @@ int mtrr_add_page(unsigned long base, un
+       }
+       if (base & size_or_mask || size & size_or_mask) {
+-              printk("mtrr: base or size exceeds the MTRR width\n");
++              printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n");
+               return -EINVAL;
+       }
+@@ -348,7 +350,7 @@ int mtrr_add_page(unsigned long base, un
+               if (ltype != type) {
+                       if (type == MTRR_TYPE_UNCACHABLE)
+                               continue;
+-                      printk ("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
++                      printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
+                            base, size, attrib_to_str(ltype),
+                            attrib_to_str(type));
+                       goto out;
+@@ -364,7 +366,7 @@ int mtrr_add_page(unsigned long base, un
+               set_mtrr(i, base, size, type);
+               usage_table[i] = 1;
+       } else
+-              printk("mtrr: no more MTRRs available\n");
++              printk(KERN_INFO "mtrr: no more MTRRs available\n");
+       error = i;
+  out:
+       up(&main_lock);
+@@ -412,8 +414,8 @@ mtrr_add(unsigned long base, unsigned lo
+        char increment)
+ {
+       if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
+-              printk("mtrr: size and base must be multiples of 4 kiB\n");
+-              printk("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
++              printk(KERN_WARNING "mtrr: size and base must be multiples of 4 kiB\n");
++              printk(KERN_DEBUG "mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+               return -EINVAL;
+       }
+       return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
+@@ -458,28 +460,28 @@ int mtrr_del_page(int reg, unsigned long
+                       }
+               }
+               if (reg < 0) {
+-                      printk("mtrr: no MTRR for %lx000,%lx000 found\n", base,
++                      printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base,
+                              size);
+                       goto out;
+               }
+       }
+       if (reg >= max) {
+-              printk("mtrr: register: %d too big\n", reg);
++              printk(KERN_WARNING "mtrr: register: %d too big\n", reg);
+               goto out;
+       }
+       if (is_cpu(CYRIX) && !use_intel()) {
+               if ((reg == 3) && arr3_protected) {
+-                      printk("mtrr: ARR3 cannot be changed\n");
++                      printk(KERN_WARNING "mtrr: ARR3 cannot be changed\n");
+                       goto out;
+               }
+       }
+       mtrr_if->get(reg, &lbase, &lsize, &ltype);
+       if (lsize < 1) {
+-              printk("mtrr: MTRR %d not used\n", reg);
++              printk(KERN_WARNING "mtrr: MTRR %d not used\n", reg);
+               goto out;
+       }
+       if (usage_table[reg] < 1) {
+-              printk("mtrr: reg: %d has count=0\n", reg);
++              printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg);
+               goto out;
+       }
+       if (--usage_table[reg] < 1)
+@@ -508,8 +510,8 @@ int
+ mtrr_del(int reg, unsigned long base, unsigned long size)
+ {
+       if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
+-              printk("mtrr: size and base must be multiples of 4 kiB\n");
+-              printk("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
++              printk(KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
++              printk(KERN_DEBUG "mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+               return -EINVAL;
+       }
+       return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
+@@ -677,7 +679,7 @@ static int __init mtrr_init(void)
+                       break;
+               }
+       }
+-      printk("mtrr: v%s\n",MTRR_VERSION);
++      printk(KERN_INFO "mtrr: v%s\n",MTRR_VERSION);
+       if (mtrr_if) {
+               set_num_var_ranges();
+@@ -701,5 +703,5 @@ char *mtrr_strings[MTRR_NUM_TYPES] =
+     "write-back",               /* 6 */
+ };
+-subsys_initcall(mtrr_init);
++core_initcall(mtrr_init);
+--- linux-2.6.0-test1/arch/i386/kernel/cpu/proc.c      2003-06-14 12:18:33.000000000 -0700
++++ 25/arch/i386/kernel/cpu/proc.c     2003-07-19 17:04:06.000000000 -0700
+@@ -60,7 +60,7 @@ static int show_cpuinfo(struct seq_file 
+       int fpu_exception;
+ #ifdef CONFIG_SMP
+-      if (!(cpu_online_map & (1<<n)))
++      if (!cpu_online(n))
+               return 0;
+ #endif
+       seq_printf(m, "processor\t: %d\n"
+--- linux-2.6.0-test1/arch/i386/kernel/entry.S 2003-07-13 21:44:34.000000000 -0700
++++ 25/arch/i386/kernel/entry.S        2003-07-19 17:06:37.000000000 -0700
+@@ -48,6 +48,18 @@
+ #include <asm/smp.h>
+ #include <asm/page.h>
+ #include "irq_vectors.h"
++        /* We do not recover from a stack overflow, but at least
++         * we know it happened and should be able to track it down.
++         */
++#ifdef CONFIG_STACK_OVERFLOW_TEST
++#define STACK_OVERFLOW_TEST \
++        testl $7680,%esp;    \
++        jnz   10f;            \
++        call  stack_overflow; \
++10:
++#else
++#define STACK_OVERFLOW_TEST
++#endif
+ EBX           = 0x00
+ ECX           = 0x04
+@@ -98,7 +110,8 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+       pushl %ebx; \
+       movl $(__USER_DS), %edx; \
+       movl %edx, %ds; \
+-      movl %edx, %es;
++      movl %edx, %es; \
++        STACK_OVERFLOW_TEST
+ #define RESTORE_INT_REGS \
+       popl %ebx;      \
+@@ -298,6 +311,19 @@ syscall_exit:
+       testw $_TIF_ALLWORK_MASK, %cx   # current->work
+       jne syscall_exit_work
+ restore_all:
++#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
++      movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
++      movb CS(%esp), %al
++      testl $(VM_MASK | 3), %eax
++      jz resume_kernelX               # returning to kernel or vm86-space
++
++      cmpl $0,TI_PRE_COUNT(%ebx)      # non-zero preempt_count ?
++      jz resume_kernelX
++        
++        int $3
++        
++resume_kernelX:
++#endif
+       RESTORE_ALL
+       # perform work that needs to be done immediately before resumption
+@@ -878,5 +904,6 @@ ENTRY(sys_call_table)
+       .long sys_fstatfs64     
+       .long sys_tgkill        /* 270 */
+       .long sys_utimes
+- 
++      .long sys_mknod64
++
+ nr_syscalls=(.-sys_call_table)/4
+--- linux-2.6.0-test1/arch/i386/kernel/io_apic.c       2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/i386/kernel/io_apic.c      2003-07-19 17:04:06.000000000 -0700
+@@ -249,14 +249,14 @@ static void clear_IO_APIC (void)
+                       clear_IO_APIC_pin(apic, pin);
+ }
+-static void set_ioapic_affinity (unsigned int irq, unsigned long cpu_mask)
++static void set_ioapic_affinity(unsigned int irq, cpumask_t cpumask)
+ {
+       unsigned long flags;
+       int pin;
+       struct irq_pin_list *entry = irq_2_pin + irq;
+       unsigned int apicid_value;
+       
+-      apicid_value = cpu_mask_to_apicid(cpu_mask);
++      apicid_value = cpu_mask_to_apicid(mk_cpumask_const(cpumask));
+       /* Prepare to do the io_apic_write */
+       apicid_value = apicid_value << 24;
+       spin_lock_irqsave(&ioapic_lock, flags);
+@@ -286,9 +286,9 @@ static void set_ioapic_affinity (unsigne
+ #  define Dprintk(x...) 
+ # endif
+-extern unsigned long irq_affinity[NR_IRQS];
++extern cpumask_t irq_affinity[NR_IRQS];
+-static int __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS];
++static cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS];
+ #define IRQBALANCE_CHECK_ARCH -999
+ static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH;
+@@ -307,8 +307,7 @@ struct irq_cpu_info {
+ #define IDLE_ENOUGH(cpu,now) \
+               (idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1))
+-#define IRQ_ALLOWED(cpu,allowed_mask) \
+-              ((1 << cpu) & (allowed_mask))
++#define IRQ_ALLOWED(cpu, allowed_mask)        cpu_isset(cpu, allowed_mask)
+ #define CPU_TO_PACKAGEINDEX(i) \
+               ((physical_balance && i > cpu_sibling_map[i]) ? cpu_sibling_map[i] : i)
+@@ -320,7 +319,7 @@ struct irq_cpu_info {
+ long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL;
+-static unsigned long move(int curr_cpu, unsigned long allowed_mask,
++static unsigned long move(int curr_cpu, cpumask_t allowed_mask,
+                       unsigned long now, int direction)
+ {
+       int search_idle = 1;
+@@ -350,20 +349,20 @@ inside:
+ static inline void balance_irq(int cpu, int irq)
+ {
+       unsigned long now = jiffies;
+-      unsigned long allowed_mask;
++      cpumask_t allowed_mask;
+       unsigned int new_cpu;
+               
+       if (irqbalance_disabled)
+               return; 
+-      allowed_mask = cpu_online_map & irq_affinity[irq];
++      cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]);
+       new_cpu = move(cpu, allowed_mask, now, 1);
+       if (cpu != new_cpu) {
+               irq_desc_t *desc = irq_desc + irq;
+               unsigned long flags;
+               spin_lock_irqsave(&desc->lock, flags);
+-              pending_irq_balance_cpumask[irq] = 1 << new_cpu;
++              pending_irq_balance_cpumask[irq] = cpumask_of_cpu(new_cpu);
+               spin_unlock_irqrestore(&desc->lock, flags);
+       }
+ }
+@@ -399,8 +398,7 @@ static void do_irq_balance(void)
+       int tmp_loaded, first_attempt = 1;
+       unsigned long tmp_cpu_irq;
+       unsigned long imbalance = 0;
+-      unsigned long allowed_mask;
+-      unsigned long target_cpu_mask;
++      cpumask_t allowed_mask, target_cpu_mask, tmp;
+       for (i = 0; i < NR_CPUS; i++) {
+               int package_index;
+@@ -549,10 +547,11 @@ tryanotherirq:
+                                       CPU_IRQ(cpu_sibling_map[min_loaded]))
+               min_loaded = cpu_sibling_map[min_loaded];
+-      allowed_mask = cpu_online_map & irq_affinity[selected_irq];
+-      target_cpu_mask = 1 << min_loaded;
++      cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]);
++      target_cpu_mask = cpumask_of_cpu(min_loaded);
++      cpus_and(tmp, target_cpu_mask, allowed_mask);
+-      if (target_cpu_mask & allowed_mask) {
++      if (!cpus_empty(tmp)) {
+               irq_desc_t *desc = irq_desc + selected_irq;
+               unsigned long flags;
+@@ -560,7 +559,8 @@ tryanotherirq:
+                               selected_irq, min_loaded);
+               /* mark for change destination */
+               spin_lock_irqsave(&desc->lock, flags);
+-              pending_irq_balance_cpumask[selected_irq] = 1 << min_loaded;
++              pending_irq_balance_cpumask[selected_irq] =
++                                      cpumask_of_cpu(min_loaded);
+               spin_unlock_irqrestore(&desc->lock, flags);
+               /* Since we made a change, come back sooner to 
+                * check for more variation.
+@@ -591,8 +591,9 @@ int balanced_irq(void *unused)
+       daemonize("kirqd");
+       
+       /* push everything to CPU 0 to give us a starting point.  */
+-      for (i = 0 ; i < NR_IRQS ; i++)
+-              pending_irq_balance_cpumask[i] = 1;
++      for (i = 0 ; i < NR_IRQS ; i++) {
++              pending_irq_balance_cpumask[i] = cpumask_of_cpu(0);
++      }
+ repeat:
+       set_current_state(TASK_INTERRUPTIBLE);
+@@ -611,7 +612,9 @@ static int __init balanced_irq_init(void
+ {
+       int i;
+       struct cpuinfo_x86 *c;
++      cpumask_t tmp;
++      cpus_shift_right(tmp, cpu_online_map, 2);
+         c = &boot_cpu_data;
+       /* When not overwritten by the command line ask subarchitecture. */
+       if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH)
+@@ -628,7 +631,7 @@ static int __init balanced_irq_init(void
+        * Enable physical balance only if more than 1 physical processor
+        * is present
+        */
+-      if (smp_num_siblings > 1 && cpu_online_map >> 2)
++      if (smp_num_siblings > 1 && !cpus_empty(tmp))
+               physical_balance = 1;
+       for (i = 0; i < NR_CPUS; i++) {
+@@ -667,14 +670,14 @@ static int __init irqbalance_disable(cha
+ __setup("noirqbalance", irqbalance_disable);
+-static void set_ioapic_affinity (unsigned int irq, unsigned long mask);
++static void set_ioapic_affinity(unsigned int irq, cpumask_t mask);
+ static inline void move_irq(int irq)
+ {
+       /* note - we hold the desc->lock */
+-      if (unlikely(pending_irq_balance_cpumask[irq])) {
++      if (unlikely(!cpus_empty(pending_irq_balance_cpumask[irq]))) {
+               set_ioapic_affinity(irq, pending_irq_balance_cpumask[irq]);
+-              pending_irq_balance_cpumask[irq] = 0;
++              cpus_clear(pending_irq_balance_cpumask[irq]);
+       }
+ }
+@@ -682,6 +685,21 @@ __initcall(balanced_irq_init);
+ #else /* !SMP */
+ static inline void move_irq(int irq) { }
++
++void send_IPI_self(int vector)
++{
++      unsigned int cfg;
++
++      /*
++       * Wait for idle.
++       */
++      apic_wait_icr_idle();
++      cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
++      /*
++       * Send the IPI. The write to APIC_ICR fires this off.
++       */
++      apic_write_around(APIC_ICR, cfg);
++}
+ #endif /* defined(CONFIG_SMP) */
+@@ -822,7 +840,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, 
+  * we need to reprogram the ioredtbls to cater for the cpus which have come online
+  * so mask in all cases should simply be TARGET_CPUS
+  */
+-void __init setup_ioapic_dest (unsigned long mask)
++void __init setup_ioapic_dest(cpumask_t mask)
+ {
+       int pin, ioapic, irq, irq_entry;
+@@ -1598,7 +1616,7 @@ void disable_IO_APIC(void)
+ static void __init setup_ioapic_ids_from_mpc(void)
+ {
+       union IO_APIC_reg_00 reg_00;
+-      unsigned long phys_id_present_map;
++      physid_mask_t phys_id_present_map;
+       int apic;
+       int i;
+       unsigned char old_id;
+@@ -1608,6 +1626,10 @@ static void __init setup_ioapic_ids_from
+               /* This gets done during IOAPIC enumeration for ACPI. */
+               return;
++      /*
++       * This is broken; anything with a real cpu count has to
++       * circumvent this idiocy regardless.
++       */
+       phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
+       /*
+@@ -1639,18 +1661,20 @@ static void __init setup_ioapic_ids_from
+                                       mp_ioapics[apic].mpc_apicid)) {
+                       printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
+                               apic, mp_ioapics[apic].mpc_apicid);
+-                      for (i = 0; i < 0xf; i++)
+-                              if (!(phys_id_present_map & (1 << i)))
++                      for (i = 0; i < APIC_BROADCAST_ID; i++)
++                              if (!physid_isset(i, phys_id_present_map))
+                                       break;
+-                      if (i >= 0xf)
++                      if (i >= APIC_BROADCAST_ID)
+                               panic("Max APIC ID exceeded!\n");
+                       printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+                               i);
+-                      phys_id_present_map |= 1 << i;
++                      physid_set(i, phys_id_present_map);
+                       mp_ioapics[apic].mpc_apicid = i;
+               } else {
++                      physid_mask_t tmp;
++                      tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid);
+                       printk("Setting %d in the phys_id_present_map\n", mp_ioapics[apic].mpc_apicid);
+-                      phys_id_present_map |= apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid);
++                      physids_or(phys_id_present_map, phys_id_present_map, tmp);
+               }
+@@ -2220,7 +2244,8 @@ late_initcall(io_apic_bug_finalize);
+ int __init io_apic_get_unique_id (int ioapic, int apic_id)
+ {
+       union IO_APIC_reg_00 reg_00;
+-      static unsigned long apic_id_map = 0;
++      static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
++      physid_mask_t tmp;
+       unsigned long flags;
+       int i = 0;
+@@ -2233,8 +2258,8 @@ int __init io_apic_get_unique_id (int io
+        *      advantage of new APIC bus architecture.
+        */
+-      if (!apic_id_map)
+-              apic_id_map = phys_cpu_present_map;
++      if (physids_empty(apic_id_map))
++              apic_id_map = ioapic_phys_id_map(phys_cpu_present_map);
+       spin_lock_irqsave(&ioapic_lock, flags);
+       reg_00.raw = io_apic_read(ioapic, 0);
+@@ -2266,7 +2291,8 @@ int __init io_apic_get_unique_id (int io
+               apic_id = i;
+       } 
+-      apic_id_map |= apicid_to_cpu_present(apic_id);
++      tmp = apicid_to_cpu_present(apic_id);
++      physids_or(apic_id_map, apic_id_map, tmp);
+       if (reg_00.bits.ID != apic_id) {
+               reg_00.bits.ID = apic_id;
+--- linux-2.6.0-test1/arch/i386/kernel/irq.c   2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/i386/kernel/irq.c  2003-07-19 17:04:06.000000000 -0700
+@@ -45,8 +45,6 @@
+ #include <asm/desc.h>
+ #include <asm/irq.h>
+-
+-
+ /*
+  * Linux has a controller-independent x86 interrupt architecture.
+  * every controller has a 'controller-template', that is used
+@@ -889,13 +887,13 @@ int setup_irq(unsigned int irq, struct i
+ static struct proc_dir_entry * root_irq_dir;
+ static struct proc_dir_entry * irq_dir [NR_IRQS];
+-#define HEX_DIGITS 8
++#define HEX_DIGITS (2*sizeof(cpumask_t))
+-static unsigned int parse_hex_value (const char __user *buffer,
+-              unsigned long count, unsigned long *ret)
++static unsigned int parse_hex_value(const char __user *buffer,
++              unsigned long count, cpumask_t *ret)
+ {
+-      unsigned char hexnum [HEX_DIGITS];
+-      unsigned long value;
++      unsigned char hexnum[HEX_DIGITS];
++      cpumask_t value = CPU_MASK_NONE;
+       int i;
+       if (!count)
+@@ -909,10 +907,10 @@ static unsigned int parse_hex_value (con
+        * Parse the first 8 characters as a hex string, any non-hex char
+        * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+        */
+-      value = 0;
+       for (i = 0; i < count; i++) {
+               unsigned int c = hexnum[i];
++              int k;
+               switch (c) {
+                       case '0' ... '9': c -= '0'; break;
+@@ -921,7 +919,10 @@ static unsigned int parse_hex_value (con
+               default:
+                       goto out;
+               }
+-              value = (value << 4) | c;
++              cpus_shift_left(value, value, 4);
++              for (k = 0; k < 4; ++k)
++                      if (test_bit(k, (unsigned long *)&c))
++                              cpu_set(k, value);
+       }
+ out:
+       *ret = value;
+@@ -930,22 +931,35 @@ out:
+ #ifdef CONFIG_SMP
+-static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
++static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
++
++cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
+-unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
+-static int irq_affinity_read_proc (char *page, char **start, off_t off,
++static int irq_affinity_read_proc(char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
++      int k, len;
++      cpumask_t tmp = irq_affinity[(long)data];
++
+       if (count < HEX_DIGITS+1)
+               return -EINVAL;
+-      return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
++
++      len = 0;
++      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
++              int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
++              len += j;
++              page += j;
++              cpus_shift_right(tmp, tmp, 16);
++      }
++      len += sprintf(page, "\n");
++      return len;
+ }
+-static int irq_affinity_write_proc (struct file *file, const char __user *buffer,
++static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
+                                       unsigned long count, void *data)
+ {
+-      int irq = (long) data, full_count = count, err;
+-      unsigned long new_value;
++      int irq = (long)data, full_count = count, err;
++      cpumask_t new_value, tmp;
+       if (!irq_desc[irq].handler->set_affinity)
+               return -EIO;
+@@ -957,11 +971,13 @@ static int irq_affinity_write_proc (stru
+        * way to make the system unusable accidentally :-) At least
+        * one online CPU still has to be targeted.
+        */
+-      if (!(new_value & cpu_online_map))
++      cpus_and(tmp, new_value, cpu_online_map);
++      if (cpus_empty(tmp))
+               return -EINVAL;
+       irq_affinity[irq] = new_value;
+-      irq_desc[irq].handler->set_affinity(irq, new_value);
++      irq_desc[irq].handler->set_affinity(irq,
++                                      cpumask_of_cpu(first_cpu(new_value)));
+       return full_count;
+ }
+@@ -980,8 +996,9 @@ static int prof_cpu_mask_read_proc (char
+ static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
+                                       unsigned long count, void *data)
+ {
+-      unsigned long *mask = (unsigned long *) data, full_count = count, err;
+-      unsigned long new_value;
++      cpumask_t *mask = (cpumask_t *)data;
++      unsigned long full_count = count, err;
++      cpumask_t new_value;
+       err = parse_hex_value(buffer, count, &new_value);
+       if (err)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/kgdb_stub.c    2003-07-19 17:04:14.000000000 -0700
+@@ -0,0 +1,2215 @@
++/*
++ *
++ * 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.
++ *
++ */
++
++/*
++ * Copyright (c) 2000 VERITAS Software Corporation.
++ * 
++ */
++/****************************************************************************
++ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
++ *
++ *  Module name: remcom.c $
++ *  Revision: 1.34 $
++ *  Date: 91/03/09 12:29:49 $
++ *  Contributor:     Lake Stevens Instrument Division$
++ *
++ *  Description:     low level support for gdb debugger. $
++ *
++ *  Considerations:  only works on target hardware $
++ *
++ *  Written by:            Glenn Engel $
++ *  Updated by:            David Grothe <dave@gcom.com>
++ *  ModuleState:     Experimental $
++ *
++ *  NOTES:         See Below $
++ *
++ *  Modified for 386 by Jim Kingdon, Cygnus Support.
++ *  Compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
++ *
++ *  Changes to allow auto initilization.  All that is needed is that it
++ *  be linked with the kernel and a break point (int 3) be executed.
++ *  The header file <asm/kgdb.h> defines BREAKPOINT to allow one to do
++ *  this. It should also be possible, once the interrupt system is up, to
++ *  call putDebugChar("+").  Once this is done, the remote debugger should
++ *  get our attention by sending a ^C in a packet. George Anzinger 
++ *  <george@mvista.com>
++ *  Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com>
++ *  Added thread support, support for multiple processors,
++ *    support for ia-32(x86) hardware debugging.
++ *    Amit S. Kale ( akale@veritas.com )
++ *
++ *
++ *  To enable debugger support, two things need to happen.  One, a
++ *  call to set_debug_traps() is necessary in order to allow any breakpoints
++ *  or error conditions to be properly intercepted and reported to gdb.
++ *  Two, a breakpoint needs to be generated to begin communication.  This
++ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
++ *  simulates a breakpoint by executing an int 3.
++ *
++ *************
++ *
++ *    The following gdb commands are supported:
++ *
++ * command        function                               Return value
++ *
++ *    g                   return the value of the CPU registers  hex data or ENN
++ *    G                   set the value of the CPU registers     OK or ENN
++ *
++ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA    hex data or ENN
++ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA    OK or ENN
++ *
++ *    c                   Resume at current address              SNN   ( signal NN)
++ *    cAA..AA     Continue at address AA..AA             SNN
++ *
++ *    s                   Step one instruction                   SNN
++ *    sAA..AA     Step one instruction from AA..AA       SNN
++ *
++ *    k                   kill
++ *
++ *    ?                   What was the last sigval ?             SNN   (signal NN)
++ *
++ * All commands and responses are sent with a packet which includes a
++ * checksum.  A packet consists of
++ *
++ * $<packet info>#<checksum>.
++ *
++ * where
++ * <packet info> :: <characters representing the command or response>
++ * <checksum>  :: < two hex digits computed as modulo 256 sum of <packetinfo>>
++ *
++ * When a packet is received, it is first acknowledged with either '+' or '-'.
++ * '+' indicates a successful transfer.        '-' indicates a failed transfer.
++ *
++ * Example:
++ *
++ * Host:                Reply:
++ * $m0,10#2a             +$00010203040506070809101112131415#42
++ *
++ ****************************************************************************/
++#define KGDB_VERSION "<20030530.0126.22>"
++#include <linux/config.h>
++#include <linux/types.h>
++#include <asm/string.h>               /* for strcpy */
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <asm/vm86.h>
++#include <asm/system.h>
++#include <asm/ptrace.h>               /* for linux pt_regs struct */
++#include <asm/kgdb_local.h>
++#include <linux/list.h>
++#include <asm/atomic.h>
++#include <asm/processor.h>
++#include <linux/irq.h>
++#include <asm/desc.h>
++
++/************************************************************************
++ *
++ * external low-level support routines
++ */
++typedef void (*Function) (void);      /* pointer to a function */
++
++/* Thread reference */
++typedef unsigned char threadref[8];
++
++extern void putDebugChar(int);        /* write a single character      */
++extern int getDebugChar(void);        /* read and return a single char */
++
++/************************************************************************/
++/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
++/* at least NUMREGBYTES*2 are needed for register packets */
++/* Longer buffer is needed to list all threads */
++#define BUFMAX 1024
++
++char *kgdb_version = KGDB_VERSION;
++
++/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
++int debug_regs = 0;           /* set to non-zero to print registers */
++
++/* filled in by an external module */
++char *gdb_module_offsets;
++
++static const char hexchars[] = "0123456789abcdef";
++
++/* Number of bytes of registers.  */
++#define NUMREGBYTES 64
++/*
++ * Note that this register image is in a different order than
++ * the register image that Linux produces at interrupt time.
++ *
++ * Linux's register image is defined by struct pt_regs in ptrace.h.
++ * Just why GDB uses a different order is a historical mystery.
++ */
++enum regnames { _EAX,         /* 0 */
++      _ECX,                   /* 1 */
++      _EDX,                   /* 2 */
++      _EBX,                   /* 3 */
++      _ESP,                   /* 4 */
++      _EBP,                   /* 5 */
++      _ESI,                   /* 6 */
++      _EDI,                   /* 7 */
++      _PC /* 8 also known as eip */ ,
++      _PS /* 9 also known as eflags */ ,
++      _CS,                    /* 10 */
++      _SS,                    /* 11 */
++      _DS,                    /* 12 */
++      _ES,                    /* 13 */
++      _FS,                    /* 14 */
++      _GS                     /* 15 */
++};
++
++/***************************  ASSEMBLY CODE MACROS *************************/
++/*
++ * Put the error code here just in case the user cares.       
++ * Likewise, the vector number here (since GDB only gets the signal
++ * number through the usual means, and that's not very specific). 
++ * The called_from is the return address so he can tell how we entered kgdb.
++ * This will allow him to seperate out the various possible entries. 
++ */
++#define REMOTE_DEBUG 0                /* set != to turn on printing (also available in info) */
++
++#define PID_MAX PID_MAX_DEFAULT
++
++#ifdef CONFIG_SMP
++void smp_send_nmi_allbutself(void);
++#define IF_SMP(x) x
++#undef MAX_NO_CPUS
++#ifndef CONFIG_NO_KGDB_CPUS
++#define CONFIG_NO_KGDB_CPUS 2
++#endif
++#if CONFIG_NO_KGDB_CPUS > NR_CPUS
++#define MAX_NO_CPUS NR_CPUS
++#else
++#define MAX_NO_CPUS CONFIG_NO_KGDB_CPUS
++#endif
++#define hold_init hold_on_sstep: 1,
++#define MAX_CPU_MASK (unsigned long)((1LL << MAX_NO_CPUS) - 1LL)
++#define NUM_CPUS num_online_cpus()
++#else
++#define IF_SMP(x)
++#define hold_init
++#undef MAX_NO_CPUS
++#define MAX_NO_CPUS 1
++#define NUM_CPUS 1
++#endif
++#define NOCPU (struct task_struct *)0xbad1fbad
++/* *INDENT-OFF*        */
++struct kgdb_info {
++      int used_malloc;
++      void *called_from;
++      long long entry_tsc;
++      int errcode;
++      int vector;
++      int print_debug_info;
++#ifdef CONFIG_SMP
++      int hold_on_sstep;
++      struct {
++              volatile struct task_struct *task;
++              int pid;
++              int hold;
++              struct pt_regs *regs;
++      } cpus_waiting[MAX_NO_CPUS];
++#endif
++} kgdb_info = {hold_init print_debug_info:REMOTE_DEBUG, vector:-1};
++
++/* *INDENT-ON*        */
++
++#define used_m kgdb_info.used_malloc
++/*
++ * This is little area we set aside to contain the stack we 
++ * need to build to allow gdb to call functions.  We use one
++ * per cpu to avoid locking issues.  We will do all this work
++ * with interrupts off so that should take care of the protection
++ * issues.
++ */
++#define LOOKASIDE_SIZE 200    /* should be more than enough */
++#define MALLOC_MAX   200      /* Max malloc size */
++struct {
++      unsigned int esp;
++      int array[LOOKASIDE_SIZE];
++} fn_call_lookaside[MAX_NO_CPUS];
++
++static int trap_cpu;
++static unsigned int OLD_esp;
++
++#define END_OF_LOOKASIDE  &fn_call_lookaside[trap_cpu].array[LOOKASIDE_SIZE]
++#define IF_BIT 0x200
++#define TF_BIT 0x100
++
++#define MALLOC_ROUND 8-1
++
++static char malloc_array[MALLOC_MAX];
++IF_SMP(static void to_gdb(const char *mess));
++void *
++malloc(int size)
++{
++
++      if (size <= (MALLOC_MAX - used_m)) {
++              int old_used = used_m;
++              used_m += ((size + MALLOC_ROUND) & (~MALLOC_ROUND));
++              return &malloc_array[old_used];
++      } else {
++              return NULL;
++      }
++}
++
++/*
++ * Gdb calls functions by pushing agruments, including a return address 
++ * on the stack and the adjusting EIP to point to the function.        The 
++ * whole assumption in GDB is that we are on a different stack than the
++ * one the "user" i.e. code that hit the break point, is on.  This, of
++ * course is not true in the kernel.  Thus various dodges are needed to
++ * do the call without directly messing with EIP (which we can not change
++ * as it is just a location and not a register.        To adjust it would then
++ * require that we move every thing below EIP up or down as needed.  This
++ * will not work as we may well have stack relative pointer on the stack
++ * (such as the pointer to regs, for example).
++
++ * So here is what we do:
++ * We detect gdb attempting to store into the stack area and instead, store
++ * into the fn_call_lookaside.array at the same relative location as if it 
++ * were the area ESP pointed at.  We also trap ESP modifications
++ * and uses these to adjust fn_call_lookaside.esp.  On entry 
++ * fn_call_lookaside.esp will be set to point at the last entry in
++ * fn_call_lookaside.array.  This allows us to check if it has changed, and 
++ * if so, on exit, we add the registers we will use to do the move and a
++ * trap/ interrupt return exit sequence.  We then adjust the eflags in the
++ * regs array (remember we now have a copy in the fn_call_lookaside.array) to
++ * kill the interrupt bit, AND we change EIP to point at our set up stub.
++ * As part of the register set up we preset the registers to point at the
++ * begining and end of the fn_call_lookaside.array, so all the stub needs to
++ * do is move words from the array to the stack until ESP= the desired value
++ * then do the rti.  This will then transfer to the desired function with 
++ * all the correct registers.  Nifty huh?
++ */
++extern asmlinkage void fn_call_stub(void);
++extern asmlinkage void fn_rtn_stub(void);
++/*                                       *INDENT-OFF*  */
++__asm__("fn_rtn_stub:\n\t"
++      "movl %eax,%esp\n\t"
++      "fn_call_stub:\n\t"
++      "1:\n\t"
++      "addl $-4,%ebx\n\t"
++      "movl (%ebx), %eax\n\t"
++      "pushl %eax\n\t"
++      "cmpl %esp,%ecx\n\t"
++      "jne  1b\n\t"
++      "popl %eax\n\t" 
++      "popl %ebx\n\t" 
++      "popl %ecx\n\t" 
++      "iret \n\t");
++/*                                         *INDENT-ON*  */
++#define gdb_i386vector        kgdb_info.vector
++#define gdb_i386errcode kgdb_info.errcode
++#define waiting_cpus  kgdb_info.cpus_waiting
++#define remote_debug  kgdb_info.print_debug_info
++#define hold_cpu(cpu) kgdb_info.cpus_waiting[cpu].hold
++/* gdb locks */
++
++#ifdef CONFIG_SMP
++static int in_kgdb_called;
++static spinlock_t waitlocks[MAX_NO_CPUS] =
++    {[0 ... MAX_NO_CPUS - 1] = SPIN_LOCK_UNLOCKED };
++/*
++ * The following array has the thread pointer of each of the "other"
++ * cpus.  We make it global so it can be seen by gdb.
++ */
++volatile int in_kgdb_entry_log[MAX_NO_CPUS];
++volatile struct pt_regs *in_kgdb_here_log[MAX_NO_CPUS];
++/*
++static spinlock_t continuelocks[MAX_NO_CPUS];
++*/
++spinlock_t kgdb_spinlock = SPIN_LOCK_UNLOCKED;
++/* waiters on our spinlock plus us */
++static atomic_t spinlock_waiters = ATOMIC_INIT(1);
++static int spinlock_count = 0;
++static int spinlock_cpu = 0;
++/*
++ * Note we use nested spin locks to account for the case where a break
++ * point is encountered when calling a function by user direction from
++ * kgdb. Also there is the memory exception recursion to account for.
++ * Well, yes, but this lets other cpus thru too.  Lets add a
++ * cpu id to the lock.
++ */
++#define KGDB_SPIN_LOCK(x) if( spinlock_count == 0 || \
++                            spinlock_cpu != smp_processor_id()){\
++                                    atomic_inc(&spinlock_waiters); \
++                                    while (! spin_trylock(x)) {\
++                                          in_kgdb(&regs);\
++                                    }\
++                                    atomic_dec(&spinlock_waiters); \
++                                    spinlock_count = 1; \
++                                    spinlock_cpu = smp_processor_id(); \
++                        }else{  \
++                                    spinlock_count++; \
++                        }
++#define KGDB_SPIN_UNLOCK(x) if( --spinlock_count == 0) spin_unlock(x)
++#else
++unsigned kgdb_spinlock = 0;
++#define KGDB_SPIN_LOCK(x) --*x
++#define KGDB_SPIN_UNLOCK(x) ++*x
++#endif
++
++int
++hex(char ch)
++{
++      if ((ch >= 'a') && (ch <= 'f'))
++              return (ch - 'a' + 10);
++      if ((ch >= '0') && (ch <= '9'))
++              return (ch - '0');
++      if ((ch >= 'A') && (ch <= 'F'))
++              return (ch - 'A' + 10);
++      return (-1);
++}
++
++/* scan for the sequence $<data>#<checksum>   */
++void
++getpacket(char *buffer)
++{
++      unsigned char checksum;
++      unsigned char xmitcsum;
++      int i;
++      int count;
++      char ch;
++
++      do {
++              /* wait around for the start character, ignore all other characters */
++              while ((ch = (getDebugChar() & 0x7f)) != '$') ;
++              checksum = 0;
++              xmitcsum = -1;
++
++              count = 0;
++
++              /* now, read until a # or end of buffer is found */
++              while (count < BUFMAX) {
++                      ch = getDebugChar() & 0x7f;
++                      if (ch == '#')
++                              break;
++                      checksum = checksum + ch;
++                      buffer[count] = ch;
++                      count = count + 1;
++              }
++              buffer[count] = 0;
++
++              if (ch == '#') {
++                      xmitcsum = hex(getDebugChar() & 0x7f) << 4;
++                      xmitcsum += hex(getDebugChar() & 0x7f);
++                      if ((remote_debug) && (checksum != xmitcsum)) {
++                              printk
++                                  ("bad checksum.     My count = 0x%x, sent=0x%x. buf=%s\n",
++                                   checksum, xmitcsum, buffer);
++                      }
++
++                      if (checksum != xmitcsum)
++                              putDebugChar('-');      /* failed checksum */
++                      else {
++                              putDebugChar('+');      /* successful transfer */
++                              /* if a sequence char is present, reply the sequence ID */
++                              if (buffer[2] == ':') {
++                                      putDebugChar(buffer[0]);
++                                      putDebugChar(buffer[1]);
++                                      /* remove sequence chars from buffer */
++                                      count = strlen(buffer);
++                                      for (i = 3; i <= count; i++)
++                                              buffer[i - 3] = buffer[i];
++                              }
++                      }
++              }
++      } while (checksum != xmitcsum);
++
++      if (remote_debug)
++              printk("R:%s\n", buffer);
++}
++
++/* send the packet in buffer.  */
++
++void
++putpacket(char *buffer)
++{
++      unsigned char checksum;
++      int count;
++      char ch;
++
++      /*  $<packet info>#<checksum>. */
++      do {
++              if (remote_debug)
++                      printk("T:%s\n", buffer);
++              putDebugChar('$');
++              checksum = 0;
++              count = 0;
++
++              while ((ch = buffer[count])) {
++                      putDebugChar(ch);
++                      checksum += ch;
++                      count += 1;
++              }
++
++              putDebugChar('#');
++              putDebugChar(hexchars[checksum >> 4]);
++              putDebugChar(hexchars[checksum % 16]);
++
++      } while ((getDebugChar() & 0x7f) != '+');
++
++}
++
++static char remcomInBuffer[BUFMAX];
++static char remcomOutBuffer[BUFMAX];
++static short error;
++
++void
++debug_error(char *format, char *parm)
++{
++      if (remote_debug)
++              printk(format, parm);
++}
++
++static void
++print_regs(struct pt_regs *regs)
++{
++      printk("EAX=%08lx ", regs->eax);
++      printk("EBX=%08lx ", regs->ebx);
++      printk("ECX=%08lx ", regs->ecx);
++      printk("EDX=%08lx ", regs->edx);
++      printk("\n");
++      printk("ESI=%08lx ", regs->esi);
++      printk("EDI=%08lx ", regs->edi);
++      printk("EBP=%08lx ", regs->ebp);
++      printk("ESP=%08lx ", (long) &regs->esp);
++      printk("\n");
++      printk(" DS=%08x ", regs->xds);
++      printk(" ES=%08x ", regs->xes);
++      printk(" SS=%08x ", __KERNEL_DS);
++      printk(" FL=%08lx ", regs->eflags);
++      printk("\n");
++      printk(" CS=%08x ", regs->xcs);
++      printk(" IP=%08lx ", regs->eip);
++#if 0
++      printk(" FS=%08x ", regs->fs);
++      printk(" GS=%08x ", regs->gs);
++#endif
++      printk("\n");
++
++}                             /* print_regs */
++
++#define NEW_esp fn_call_lookaside[trap_cpu].esp
++
++static void
++regs_to_gdb_regs(int *gdb_regs, struct pt_regs *regs)
++{
++      gdb_regs[_EAX] = regs->eax;
++      gdb_regs[_EBX] = regs->ebx;
++      gdb_regs[_ECX] = regs->ecx;
++      gdb_regs[_EDX] = regs->edx;
++      gdb_regs[_ESI] = regs->esi;
++      gdb_regs[_EDI] = regs->edi;
++      gdb_regs[_EBP] = regs->ebp;
++      gdb_regs[_DS] = regs->xds;
++      gdb_regs[_ES] = regs->xes;
++      gdb_regs[_PS] = regs->eflags;
++      gdb_regs[_CS] = regs->xcs;
++      gdb_regs[_PC] = regs->eip;
++      /* Note, as we are a debugging the kernel, we will always 
++       * trap in kernel code, this means no priviledge change,
++       * and so the pt_regs structure is not completely valid.  In a non
++       * privilege change trap, only EFLAGS, CS and EIP are put on the stack,
++       * SS and ESP are not stacked, this means that the last 2 elements of
++       * pt_regs is not valid (they would normally refer to the user stack)
++       * also, using regs+1 is no good because you end up will a value that is 
++       * 2 longs (8) too high.  This used to cause stepping over functions
++       * to fail, so my fix is to use the address of regs->esp, which 
++       * should point at the end of the stack frame.  Note I have ignored
++       * completely exceptions that cause an error code to be stacked, such
++       * as double fault.  Stuart Hughes, Zentropix.
++       * original code: gdb_regs[_ESP] =  (int) (regs + 1) ; 
++
++       * this is now done on entry and moved to OLD_esp (as well as NEW_esp).
++       */
++      gdb_regs[_ESP] = NEW_esp;
++      gdb_regs[_SS] = __KERNEL_DS;
++      gdb_regs[_FS] = 0xFFFF;
++      gdb_regs[_GS] = 0xFFFF;
++}                             /* regs_to_gdb_regs */
++
++static void
++gdb_regs_to_regs(int *gdb_regs, struct pt_regs *regs)
++{
++      regs->eax = gdb_regs[_EAX];
++      regs->ebx = gdb_regs[_EBX];
++      regs->ecx = gdb_regs[_ECX];
++      regs->edx = gdb_regs[_EDX];
++      regs->esi = gdb_regs[_ESI];
++      regs->edi = gdb_regs[_EDI];
++      regs->ebp = gdb_regs[_EBP];
++      regs->xds = gdb_regs[_DS];
++      regs->xes = gdb_regs[_ES];
++      regs->eflags = gdb_regs[_PS];
++      regs->xcs = gdb_regs[_CS];
++      regs->eip = gdb_regs[_PC];
++      NEW_esp = gdb_regs[_ESP];       /* keep the value */
++#if 0                         /* can't change these */
++      regs->esp = gdb_regs[_ESP];
++      regs->xss = gdb_regs[_SS];
++      regs->fs = gdb_regs[_FS];
++      regs->gs = gdb_regs[_GS];
++#endif
++
++}                             /* gdb_regs_to_regs */
++extern void scheduling_functions_start_here(void);
++extern void scheduling_functions_end_here(void);
++#define first_sched   ((unsigned long) scheduling_functions_start_here)
++#define last_sched    ((unsigned long) scheduling_functions_end_here)
++
++int thread_list = 0;
++
++void
++get_gdb_regs(struct task_struct *p, struct pt_regs *regs, int *gdb_regs)
++{
++      unsigned long stack_page;
++      int count = 0;
++      IF_SMP(int i);
++      if (!p || p == current) {
++              regs_to_gdb_regs(gdb_regs, regs);
++              return;
++      }
++#ifdef CONFIG_SMP
++      for (i = 0; i < MAX_NO_CPUS; i++) {
++              if (p == kgdb_info.cpus_waiting[i].task) {
++                      regs_to_gdb_regs(gdb_regs,
++                                       kgdb_info.cpus_waiting[i].regs);
++                      gdb_regs[_ESP] =
++                          (int) &kgdb_info.cpus_waiting[i].regs->esp;
++
++                      return;
++              }
++      }
++#endif
++      memset(gdb_regs, 0, NUMREGBYTES);
++      gdb_regs[_ESP] = p->thread.esp;
++      gdb_regs[_PC] = p->thread.eip;
++      gdb_regs[_EBP] = *(int *) gdb_regs[_ESP];
++      gdb_regs[_EDI] = *(int *) (gdb_regs[_ESP] + 4);
++      gdb_regs[_ESI] = *(int *) (gdb_regs[_ESP] + 8);
++
++/*
++ * This code is to give a more informative notion of where a process 
++ * is waiting.        It is used only when the user asks for a thread info
++ * list.  If he then switches to the thread, s/he will find the task
++ * is in schedule, but a back trace should show the same info we come
++ * up with.  This code was shamelessly purloined from process.c.  It was
++ * then enhanced to provide more registers than simply the program 
++ * counter.
++ */
++
++      if (!thread_list) {
++              return;
++      }
++
++      if (p->state == TASK_RUNNING)
++              return;
++      stack_page = (unsigned long) p->thread_info;
++      if (gdb_regs[_ESP] < stack_page || gdb_regs[_ESP] > 8188 + stack_page)
++              return;
++      /* include/asm-i386/system.h:switch_to() pushes ebp last. */
++      do {
++              if (gdb_regs[_EBP] < stack_page ||
++                  gdb_regs[_EBP] > 8184 + stack_page)
++                      return;
++              gdb_regs[_PC] = *(unsigned long *) (gdb_regs[_EBP] + 4);
++              gdb_regs[_ESP] = gdb_regs[_EBP] + 8;
++              gdb_regs[_EBP] = *(unsigned long *) gdb_regs[_EBP];
++              if (gdb_regs[_PC] < first_sched || gdb_regs[_PC] >= last_sched)
++                      return;
++      } while (count++ < 16);
++      return;
++}
++
++/* Indicate to caller of mem2hex or hex2mem that there has been an
++   error.  */
++static volatile int mem_err = 0;
++static volatile int mem_err_expected = 0;
++static volatile int mem_err_cnt = 0;
++static int garbage_loc = -1;
++
++int
++get_char(char *addr)
++{
++      return *addr;
++}
++
++void
++set_char(char *addr, int val, int may_fault)
++{
++      /*
++       * This code traps references to the area mapped to the kernel
++       * stack as given by the regs and, instead, stores to the
++       * fn_call_lookaside[cpu].array
++       */
++      if (may_fault &&
++          (unsigned int) addr < OLD_esp &&
++          ((unsigned int) addr > (OLD_esp - (unsigned int) LOOKASIDE_SIZE))) {
++              addr = (char *) END_OF_LOOKASIDE - ((char *) OLD_esp - addr);
++      }
++      *addr = val;
++}
++
++/* convert the memory pointed to by mem into hex, placing result in buf */
++/* return a pointer to the last char put in buf (null) */
++/* If MAY_FAULT is non-zero, then we should set mem_err in response to
++   a fault; if zero treat a fault like any other fault in the stub.  */
++char *
++mem2hex(char *mem, char *buf, int count, int may_fault)
++{
++      int i;
++      unsigned char ch;
++
++      if (may_fault) {
++              mem_err_expected = 1;
++              mem_err = 0;
++      }
++      for (i = 0; i < count; i++) {
++              /* printk("%lx = ", mem) ; */
++
++              ch = get_char(mem++);
++
++              /* printk("%02x\n", ch & 0xFF) ; */
++              if (may_fault && mem_err) {
++                      if (remote_debug)
++                              printk("Mem fault fetching from addr %lx\n",
++                                     (long) (mem - 1));
++                      *buf = 0;       /* truncate buffer */
++                      return (buf);
++              }
++              *buf++ = hexchars[ch >> 4];
++              *buf++ = hexchars[ch % 16];
++      }
++      *buf = 0;
++      if (may_fault)
++              mem_err_expected = 0;
++      return (buf);
++}
++
++/* convert the hex array pointed to by buf into binary to be placed in mem */
++/* return a pointer to the character AFTER the last byte written */
++/* NOTE: We use the may fault flag to also indicate if the write is to
++ * the registers (0) or "other" memory (!=0) 
++ */
++char *
++hex2mem(char *buf, char *mem, int count, int may_fault)
++{
++      int i;
++      unsigned char ch;
++
++      if (may_fault) {
++              mem_err_expected = 1;
++              mem_err = 0;
++      }
++      for (i = 0; i < count; i++) {
++              ch = hex(*buf++) << 4;
++              ch = ch + hex(*buf++);
++              set_char(mem++, ch, may_fault);
++
++              if (may_fault && mem_err) {
++                      if (remote_debug)
++                              printk("Mem fault storing to addr %lx\n",
++                                     (long) (mem - 1));
++                      return (mem);
++              }
++      }
++      if (may_fault)
++              mem_err_expected = 0;
++      return (mem);
++}
++
++/**********************************************/
++/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
++/* RETURN NUMBER OF CHARS PROCESSED         */
++/**********************************************/
++int
++hexToInt(char **ptr, int *intValue)
++{
++      int numChars = 0;
++      int hexValue;
++
++      *intValue = 0;
++
++      while (**ptr) {
++              hexValue = hex(**ptr);
++              if (hexValue >= 0) {
++                      *intValue = (*intValue << 4) | hexValue;
++                      numChars++;
++              } else
++                      break;
++
++              (*ptr)++;
++      }
++
++      return (numChars);
++}
++
++#define stubhex(h) hex(h)
++
++static int
++stub_unpack_int(char *buff, int fieldlength)
++{
++      int nibble;
++      int retval = 0;
++
++      while (fieldlength) {
++              nibble = stubhex(*buff++);
++              retval |= nibble;
++              fieldlength--;
++              if (fieldlength)
++                      retval = retval << 4;
++      }
++      return retval;
++}
++
++static char *
++pack_hex_byte(char *pkt, int byte)
++{
++      *pkt++ = hexchars[(byte >> 4) & 0xf];
++      *pkt++ = hexchars[(byte & 0xf)];
++      return pkt;
++}
++
++#define BUF_THREAD_ID_SIZE 16
++
++static char *
++pack_threadid(char *pkt, threadref * id)
++{
++      char *limit;
++      unsigned char *altid;
++
++      altid = (unsigned char *) id;
++      limit = pkt + BUF_THREAD_ID_SIZE;
++      while (pkt < limit)
++              pkt = pack_hex_byte(pkt, *altid++);
++      return pkt;
++}
++
++static char *
++unpack_byte(char *buf, int *value)
++{
++      *value = stub_unpack_int(buf, 2);
++      return buf + 2;
++}
++
++static char *
++unpack_threadid(char *inbuf, threadref * id)
++{
++      char *altref;
++      char *limit = inbuf + BUF_THREAD_ID_SIZE;
++      int x, y;
++
++      altref = (char *) id;
++
++      while (inbuf < limit) {
++              x = stubhex(*inbuf++);
++              y = stubhex(*inbuf++);
++              *altref++ = (x << 4) | y;
++      }
++      return inbuf;
++}
++
++void
++int_to_threadref(threadref * id, int value)
++{
++      unsigned char *scan;
++
++      scan = (unsigned char *) id;
++      {
++              int i = 4;
++              while (i--)
++                      *scan++ = 0;
++      }
++      *scan++ = (value >> 24) & 0xff;
++      *scan++ = (value >> 16) & 0xff;
++      *scan++ = (value >> 8) & 0xff;
++      *scan++ = (value & 0xff);
++}
++
++static int
++threadref_to_int(threadref * ref)
++{
++      int i, value = 0;
++      unsigned char *scan;
++
++      scan = (char *) ref;
++      scan += 4;
++      i = 4;
++      while (i-- > 0)
++              value = (value << 8) | ((*scan++) & 0xff);
++      return value;
++}
++
++#if 1                         /* this is a hold over from 2.4 where O(1) was "sometimes" */
++extern struct task_struct *kgdb_get_idle(int cpu);
++#define idle_task(cpu) kgdb_get_idle(cpu)
++#else
++#define idle_task(cpu) init_tasks[cpu]
++#endif
++
++struct task_struct *
++getthread(int pid)
++{
++      struct task_struct *thread;
++      if (pid >= PID_MAX && pid <= (PID_MAX + MAX_NO_CPUS)) {
++
++              return idle_task(pid - PID_MAX);
++      } else {
++              /*
++               * find_task_by_pid is relatively safe all the time
++               * Other pid functions require lock downs which imply
++               * that we may be interrupting them (as we get here
++               * in the middle of most any lock down)
++               */
++              thread = find_task_by_pid(pid);
++              if (thread) {
++                      return thread;
++              }
++      }
++      return NULL;
++}
++/* *INDENT-OFF*        */
++struct hw_breakpoint {
++      unsigned enabled;
++      unsigned type;
++      unsigned len;
++      unsigned addr;
++} breakinfo[4] = { {enabled:0}, 
++                 {enabled:0}, 
++                 {enabled:0}, 
++                 {enabled:0}};
++/* *INDENT-ON*        */
++unsigned hw_breakpoint_status;
++void
++correct_hw_break(void)
++{
++      int breakno;
++      int correctit;
++      int breakbit;
++      unsigned dr7;
++
++      asm volatile ("movl %%db7, %0\n":"=r" (dr7)
++                    :);
++      /* *INDENT-OFF*  */
++      do {
++              unsigned addr0, addr1, addr2, addr3;
++              asm volatile ("movl %%db0, %0\n"
++                            "movl %%db1, %1\n"
++                            "movl %%db2, %2\n"
++                            "movl %%db3, %3\n"
++                            :"=r" (addr0), "=r"(addr1),
++                            "=r"(addr2), "=r"(addr3)
++                            :);
++      } while (0);
++      /* *INDENT-ON*  */
++      correctit = 0;
++      for (breakno = 0; breakno < 3; breakno++) {
++              breakbit = 2 << (breakno << 1);
++              if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
++                      correctit = 1;
++                      dr7 |= breakbit;
++                      dr7 &= ~(0xf0000 << (breakno << 2));
++                      dr7 |= (((breakinfo[breakno].len << 2) |
++                               breakinfo[breakno].type) << 16) <<
++                          (breakno << 2);
++                      switch (breakno) {
++                      case 0:
++                              asm volatile ("movl %0, %%dr0\n"::"r"
++                                            (breakinfo[breakno].addr));
++                              break;
++
++                      case 1:
++                              asm volatile ("movl %0, %%dr1\n"::"r"
++                                            (breakinfo[breakno].addr));
++                              break;
++
++                      case 2:
++                              asm volatile ("movl %0, %%dr2\n"::"r"
++                                            (breakinfo[breakno].addr));
++                              break;
++
++                      case 3:
++                              asm volatile ("movl %0, %%dr3\n"::"r"
++                                            (breakinfo[breakno].addr));
++                              break;
++                      }
++              } else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
++                      correctit = 1;
++                      dr7 &= ~breakbit;
++                      dr7 &= ~(0xf0000 << (breakno << 2));
++              }
++      }
++      if (correctit) {
++              asm volatile ("movl %0, %%db7\n"::"r" (dr7));
++      }
++}
++
++int
++remove_hw_break(unsigned breakno)
++{
++      if (!breakinfo[breakno].enabled) {
++              return -1;
++      }
++      breakinfo[breakno].enabled = 0;
++      return 0;
++}
++
++int
++set_hw_break(unsigned breakno, unsigned type, unsigned len, unsigned addr)
++{
++      if (breakinfo[breakno].enabled) {
++              return -1;
++      }
++      breakinfo[breakno].enabled = 1;
++      breakinfo[breakno].type = type;
++      breakinfo[breakno].len = len;
++      breakinfo[breakno].addr = addr;
++      return 0;
++}
++
++#ifdef CONFIG_SMP
++static int in_kgdb_console = 0;
++
++int
++in_kgdb(struct pt_regs *regs)
++{
++      unsigned flags;
++      int cpu = smp_processor_id();
++      in_kgdb_called = 1;
++      if (!spin_is_locked(&kgdb_spinlock)) {
++              if (in_kgdb_here_log[cpu] ||    /* we are holding this cpu */
++                  in_kgdb_console) {  /* or we are doing slow i/o */
++                      return 1;
++              }
++              return 0;
++      }
++
++      /* As I see it the only reason not to let all cpus spin on
++       * the same spin_lock is to allow selected ones to proceed.
++       * This would be a good thing, so we leave it this way.
++       * Maybe someday....  Done !
++
++       * in_kgdb() is called from an NMI so we don't pretend
++       * to have any resources, like printk() for example.  
++       */
++
++      kgdb_local_irq_save(flags);     /* only local here, to avoid hanging */
++      /*
++       * log arival of this cpu
++       * The NMI keeps on ticking.  Protect against recurring more
++       * than once, and ignor the cpu that has the kgdb lock
++       */
++      in_kgdb_entry_log[cpu]++;
++      in_kgdb_here_log[cpu] = regs;
++      if (cpu == spinlock_cpu || waiting_cpus[cpu].task) {
++              goto exit_in_kgdb;
++      }
++      /*
++       * For protection of the initilization of the spin locks by kgdb
++       * it locks the kgdb spinlock before it gets the wait locks set
++       * up.  We wait here for the wait lock to be taken.  If the
++       * kgdb lock goes away first??  Well, it could be a slow exit
++       * sequence where the wait lock is removed prior to the kgdb lock
++       * so if kgdb gets unlocked, we just exit.
++       */
++      while (spin_is_locked(&kgdb_spinlock) &&
++             !spin_is_locked(waitlocks + cpu)) ;
++      if (!spin_is_locked(&kgdb_spinlock)) {
++              goto exit_in_kgdb;
++      }
++      waiting_cpus[cpu].task = current;
++      waiting_cpus[cpu].pid = (current->pid) ? : (PID_MAX + cpu);
++      waiting_cpus[cpu].regs = regs;
++
++      spin_unlock_wait(waitlocks + cpu);
++      /*
++       * log departure of this cpu
++       */
++      waiting_cpus[cpu].task = 0;
++      waiting_cpus[cpu].pid = 0;
++      waiting_cpus[cpu].regs = 0;
++      correct_hw_break();
++      exit_in_kgdb:
++      in_kgdb_here_log[cpu] = 0;
++      kgdb_local_irq_restore(flags);
++      return 1;
++      /*
++         spin_unlock(continuelocks + smp_processor_id());
++       */
++}
++
++void
++smp__in_kgdb(struct pt_regs regs)
++{
++      ack_APIC_irq();
++      in_kgdb(&regs);
++}
++#else
++int
++in_kgdb(struct pt_regs *regs)
++{
++      return (kgdb_spinlock);
++}
++#endif
++
++void
++printexceptioninfo(int exceptionNo, int errorcode, char *buffer)
++{
++      unsigned dr6;
++      int i;
++      switch (exceptionNo) {
++      case 1:         /* debug exception */
++              break;
++      case 3:         /* breakpoint */
++              sprintf(buffer, "Software breakpoint");
++              return;
++      default:
++              sprintf(buffer, "Details not available");
++              return;
++      }
++      asm volatile ("movl %%db6, %0\n":"=r" (dr6)
++                    :);
++      if (dr6 & 0x4000) {
++              sprintf(buffer, "Single step");
++              return;
++      }
++      for (i = 0; i < 4; ++i) {
++              if (dr6 & (1 << i)) {
++                      sprintf(buffer, "Hardware breakpoint %d", i);
++                      return;
++              }
++      }
++      sprintf(buffer, "Unknown trap");
++      return;
++}
++
++/*
++ * This function does all command procesing for interfacing to gdb.
++ *
++ * NOTE:  The INT nn instruction leaves the state of the interrupt
++ *      enable flag UNCHANGED.  That means that when this routine
++ *      is entered via a breakpoint (INT 3) instruction from code
++ *      that has interrupts enabled, then interrupts will STILL BE
++ *      enabled when this routine is entered.  The first thing that
++ *      we do here is disable interrupts so as to prevent recursive
++ *      entries and bothersome serial interrupts while we are
++ *      trying to run the serial port in polled mode.
++ *
++ * For kernel version 2.1.xx the kgdb_cli() actually gets a spin lock so
++ * it is always necessary to do a restore_flags before returning
++ * so as to let go of that lock.
++ */
++int
++kgdb_handle_exception(int exceptionVector,
++                    int signo, int err_code, struct pt_regs *linux_regs)
++{
++      struct task_struct *usethread = NULL;
++      struct task_struct *thread_list_start = 0, *thread = NULL;
++      int addr, length;
++      int breakno, breaktype;
++      char *ptr;
++      int newPC;
++      threadref thref;
++      int threadid;
++      int thread_min = PID_MAX + MAX_NO_CPUS;
++      int maxthreads;
++      int nothreads;
++      unsigned long flags;
++      int gdb_regs[NUMREGBYTES / 4];
++      int dr6;
++      IF_SMP(int entry_state = 0);    /* 0, ok, 1, no nmi, 2 sync failed */
++#define NO_NMI 1
++#define NO_SYNC 2
++#define       regs    (*linux_regs)
++#define NUMREGS NUMREGBYTES/4
++      /*
++       * If the entry is not from the kernel then return to the Linux
++       * trap handler and let it process the interrupt normally.
++       */
++      if ((linux_regs->eflags & VM_MASK) || (3 & linux_regs->xcs)) {
++              printk("ignoring non-kernel exception\n");
++              print_regs(&regs);
++              return (0);
++      }
++
++      kgdb_local_irq_save(flags);
++
++      /* Get kgdb spinlock */
++
++      KGDB_SPIN_LOCK(&kgdb_spinlock);
++      rdtscll(kgdb_info.entry_tsc);
++      /*
++       * We depend on this spinlock and the NMI watch dog to control the 
++       * other cpus.  They will arrive at "in_kgdb()" as a result of the
++       * NMI and will wait there for the following spin locks to be 
++       * released.
++       */
++#ifdef CONFIG_SMP
++
++#if 0
++      if (cpu_callout_map & ~MAX_CPU_MASK) {
++              printk("kgdb : too many cpus, possibly not mapped"
++                     " in contiguous space, change MAX_NO_CPUS"
++                     " in kgdb_stub and make new kernel.\n"
++                     " cpu_callout_map is %lx\n", cpu_callout_map);
++              goto exit_just_unlock;
++      }
++#endif
++      if (spinlock_count == 1) {
++              int time, end_time, dum;
++              int i;
++              int cpu_logged_in[MAX_NO_CPUS] = {[0 ... MAX_NO_CPUS - 1] = (0)
++              };
++              if (remote_debug) {
++                      printk("kgdb : cpu %d entry, syncing others\n",
++                             smp_processor_id());
++              }
++              for (i = 0; i < MAX_NO_CPUS; i++) {
++                      /*
++                       * Use trylock as we may already hold the lock if
++                       * we are holding the cpu.  Net result is all
++                       * locked.
++                       */
++                      spin_trylock(&waitlocks[i]);
++              }
++              for (i = 0; i < MAX_NO_CPUS; i++)
++                      cpu_logged_in[i] = 0;
++              /*
++               * Wait for their arrival.  We know the watch dog is active if 
++               * in_kgdb() has ever been called, as it is always called on a 
++               * watchdog tick.
++               */
++              rdtsc(dum, time);
++              end_time = time + 2;    /* Note: we use the High order bits! */
++              i = 1;
++              if (num_online_cpus() > 1) {
++                      int me_in_kgdb = in_kgdb_entry_log[smp_processor_id()];
++                      smp_send_nmi_allbutself();
++                      while (i < num_online_cpus() && time != end_time) {
++                              int j;
++                              for (j = 0; j < MAX_NO_CPUS; j++) {
++                                      if (waiting_cpus[j].task &&
++                                          !cpu_logged_in[j]) {
++                                              i++;
++                                              cpu_logged_in[j] = 1;
++                                              if (remote_debug) {
++                                                      printk
++                                                          ("kgdb : cpu %d arrived at kgdb\n",
++                                                           j);
++                                              }
++                                              break;
++                                      } else if (!waiting_cpus[j].task &&
++                                                 !cpu_online(j)) {
++                                              waiting_cpus[j].task = NOCPU;
++                                              cpu_logged_in[j] = 1;
++                                              waiting_cpus[j].hold = 1;
++                                              break;
++                                      }
++                                      if (!waiting_cpus[j].task &&
++                                          in_kgdb_here_log[j]) {
++
++                                              int wait = 100000;
++                                              while (wait--) ;
++                                              if (!waiting_cpus[j].task &&
++                                                  in_kgdb_here_log[j]) {
++                                                      printk
++                                                          ("kgdb : cpu %d stall"
++                                                           " in in_kgdb\n",
++                                                           j);
++                                                      i++;
++                                                      cpu_logged_in[j] = 1;
++                                                      waiting_cpus[j].task =
++                                                          (struct task_struct
++                                                           *) 1;
++                                              }
++                                      }
++                              }
++
++                              if (in_kgdb_entry_log[smp_processor_id()] >
++                                  (me_in_kgdb + 10)) {
++                                      break;
++                              }
++
++                              rdtsc(dum, time);
++                      }
++                      if (i < num_online_cpus()) {
++                              printk
++                                  ("kgdb : time out, proceeding without sync\n");
++#if 0
++                              printk("kgdb : Waiting_cpus: 0 = %d, 1 = %d\n",
++                                     waiting_cpus[0].task != 0,
++                                     waiting_cpus[1].task != 0);
++                              printk("kgdb : Cpu_logged in: 0 = %d, 1 = %d\n",
++                                     cpu_logged_in[0], cpu_logged_in[1]);
++                              printk
++                                  ("kgdb : in_kgdb_here_log in: 0 = %d, 1 = %d\n",
++                                   in_kgdb_here_log[0] != 0,
++                                   in_kgdb_here_log[1] != 0);
++#endif
++                              entry_state = NO_SYNC;
++                      } else {
++#if 0
++                              int ent =
++                                  in_kgdb_entry_log[smp_processor_id()] -
++                                  me_in_kgdb;
++                              printk("kgdb : sync after %d entries\n", ent);
++#endif
++                      }
++              } else {
++                      if (remote_debug) {
++                              printk
++                                  ("kgdb : %d cpus, but watchdog not active\n"
++                                   "proceeding without locking down other cpus\n",
++                                   num_online_cpus());
++                              entry_state = NO_NMI;
++                      }
++              }
++      }
++#endif
++
++      if (remote_debug) {
++              unsigned long *lp = (unsigned long *) &linux_regs;
++
++              printk("handle_exception(exceptionVector=%d, "
++                     "signo=%d, err_code=%d, linux_regs=%p)\n",
++                     exceptionVector, signo, err_code, linux_regs);
++              if (debug_regs) {
++                      print_regs(&regs);
++                      printk("Stk: %8lx %8lx %8lx %8lx"
++                             "  %8lx %8lx %8lx %8lx\n",
++                             lp[0], lp[1], lp[2], lp[3],
++                             lp[4], lp[5], lp[6], lp[7]);
++                      printk("     %8lx %8lx %8lx %8lx"
++                             "  %8lx %8lx %8lx %8lx\n",
++                             lp[8], lp[9], lp[10], lp[11],
++                             lp[12], lp[13], lp[14], lp[15]);
++                      printk("     %8lx %8lx %8lx %8lx  "
++                             "%8lx %8lx %8lx %8lx\n",
++                             lp[16], lp[17], lp[18], lp[19],
++                             lp[20], lp[21], lp[22], lp[23]);
++                      printk("     %8lx %8lx %8lx %8lx  "
++                             "%8lx %8lx %8lx %8lx\n",
++                             lp[24], lp[25], lp[26], lp[27],
++                             lp[28], lp[29], lp[30], lp[31]);
++              }
++      }
++
++      /* Disable hardware debugging while we are in kgdb */
++      /* Get the debug register status register */
++/*                                   *INDENT-OFF*  */
++      __asm__("movl %0,%%db7"
++            : /* no output */
++            :"r"(0));
++
++      asm volatile ("movl %%db6, %0\n"
++                    :"=r" (hw_breakpoint_status)
++                    :);
++
++/*                                   *INDENT-ON*  */
++      switch (exceptionVector) {
++      case 0:         /* divide error */
++      case 1:         /* debug exception */
++      case 2:         /* NMI */
++      case 3:         /* breakpoint */
++      case 4:         /* overflow */
++      case 5:         /* bounds check */
++      case 6:         /* invalid opcode */
++      case 7:         /* device not available */
++      case 8:         /* double fault (errcode) */
++      case 10:                /* invalid TSS (errcode) */
++      case 12:                /* stack fault (errcode) */
++      case 16:                /* floating point error */
++      case 17:                /* alignment check (errcode) */
++      default:                /* any undocumented */
++              break;
++      case 11:                /* segment not present (errcode) */
++      case 13:                /* general protection (errcode) */
++      case 14:                /* page fault (special errcode) */
++      case 19:                /* cache flush denied */
++              if (mem_err_expected) {
++                      /*
++                       * This fault occured because of the
++                       * get_char or set_char routines.  These
++                       * two routines use either eax of edx to
++                       * indirectly reference the location in
++                       * memory that they are working with.
++                       * For a page fault, when we return the
++                       * instruction will be retried, so we
++                       * have to make sure that these
++                       * registers point to valid memory. 
++                       */
++                      mem_err = 1;    /* set mem error flag */
++                      mem_err_expected = 0;
++                      mem_err_cnt++;  /* helps in debugging */
++                      /* make valid address */
++                      regs.eax = (long) &garbage_loc;
++                      /* make valid address */
++                      regs.edx = (long) &garbage_loc;
++                      if (remote_debug)
++                              printk("Return after memory error: "
++                                     "mem_err_cnt=%d\n", mem_err_cnt);
++                      if (debug_regs)
++                              print_regs(&regs);
++                      goto exit_kgdb;
++              }
++              break;
++      }
++      if (remote_debug)
++              printk("kgdb : entered kgdb on cpu %d\n", smp_processor_id());
++
++      gdb_i386vector = exceptionVector;
++      gdb_i386errcode = err_code;
++      kgdb_info.called_from = __builtin_return_address(0);
++#ifdef CONFIG_SMP
++      /*
++       * OK, we can now communicate, lets tell gdb about the sync.
++       * but only if we had a problem.
++       */
++      switch (entry_state) {
++      case NO_NMI:
++              to_gdb("NMI not active, other cpus not stopped\n");
++              break;
++      case NO_SYNC:
++              to_gdb("Some cpus not stopped, see 'kgdb_info' for details\n");
++      default:;
++      }
++
++#endif
++/*
++ * Set up the gdb function call area.
++ */
++      trap_cpu = smp_processor_id();
++      OLD_esp = NEW_esp = (int) (&linux_regs->esp);
++
++      IF_SMP(once_again:)
++          /* reply to host that an exception has occurred */
++          remcomOutBuffer[0] = 'S';
++      remcomOutBuffer[1] = hexchars[signo >> 4];
++      remcomOutBuffer[2] = hexchars[signo % 16];
++      remcomOutBuffer[3] = 0;
++
++      putpacket(remcomOutBuffer);
++
++      while (1 == 1) {
++              error = 0;
++              remcomOutBuffer[0] = 0;
++              getpacket(remcomInBuffer);
++              switch (remcomInBuffer[0]) {
++              case '?':
++                      remcomOutBuffer[0] = 'S';
++                      remcomOutBuffer[1] = hexchars[signo >> 4];
++                      remcomOutBuffer[2] = hexchars[signo % 16];
++                      remcomOutBuffer[3] = 0;
++                      break;
++              case 'd':
++                      remote_debug = !(remote_debug); /* toggle debug flag */
++                      printk("Remote debug %s\n",
++                             remote_debug ? "on" : "off");
++                      break;
++              case 'g':       /* return the value of the CPU registers */
++                      get_gdb_regs(usethread, &regs, gdb_regs);
++                      mem2hex((char *) gdb_regs,
++                              remcomOutBuffer, NUMREGBYTES, 0);
++                      break;
++              case 'G':       /* set the value of the CPU registers - return OK */
++                      hex2mem(&remcomInBuffer[1],
++                              (char *) gdb_regs, NUMREGBYTES, 0);
++                      if (!usethread || usethread == current) {
++                              gdb_regs_to_regs(gdb_regs, &regs);
++                              strcpy(remcomOutBuffer, "OK");
++                      } else {
++                              strcpy(remcomOutBuffer, "E00");
++                      }
++                      break;
++
++              case 'P':{      /* set the value of a single CPU register - 
++                                 return OK */
++                              /*
++                               * For some reason, gdb wants to talk about psudo
++                               * registers (greater than 15).  These may have
++                               * meaning for ptrace, but for us it is safe to
++                               * ignor them.  We do this by dumping them into
++                               * _GS which we also ignor, but do have memory for.
++                               */
++                              int regno;
++
++                              ptr = &remcomInBuffer[1];
++                              regs_to_gdb_regs(gdb_regs, &regs);
++                              if ((!usethread || usethread == current) &&
++                                  hexToInt(&ptr, &regno) &&
++                                  *ptr++ == '=' && (regno >= 0)) {
++                                      regno =
++                                          (regno >= NUMREGS ? _GS : regno);
++                                      hex2mem(ptr, (char *) &gdb_regs[regno],
++                                              4, 0);
++                                      gdb_regs_to_regs(gdb_regs, &regs);
++                                      strcpy(remcomOutBuffer, "OK");
++                                      break;
++                              }
++                              strcpy(remcomOutBuffer, "E01");
++                              break;
++                      }
++
++                      /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
++              case 'm':
++                      /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
++                      ptr = &remcomInBuffer[1];
++                      if (hexToInt(&ptr, &addr) &&
++                          (*(ptr++) == ',') && (hexToInt(&ptr, &length))) {
++                              ptr = 0;
++                              /*
++                               * hex doubles the byte count
++                               */
++                              if (length > (BUFMAX / 2))
++                                      length = BUFMAX / 2;
++                              mem2hex((char *) addr,
++                                      remcomOutBuffer, length, 1);
++                              if (mem_err) {
++                                      strcpy(remcomOutBuffer, "E03");
++                                      debug_error("memory fault\n", NULL);
++                              }
++                      }
++
++                      if (ptr) {
++                              strcpy(remcomOutBuffer, "E01");
++                              debug_error
++                                  ("malformed read memory command: %s\n",
++                                   remcomInBuffer);
++                      }
++                      break;
++
++                      /* MAA..AA,LLLL: 
++                         Write LLLL bytes at address AA.AA return OK */
++              case 'M':
++                      /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
++                      ptr = &remcomInBuffer[1];
++                      if (hexToInt(&ptr, &addr) &&
++                          (*(ptr++) == ',') &&
++                          (hexToInt(&ptr, &length)) && (*(ptr++) == ':')) {
++                              hex2mem(ptr, (char *) addr, length, 1);
++
++                              if (mem_err) {
++                                      strcpy(remcomOutBuffer, "E03");
++                                      debug_error("memory fault\n", NULL);
++                              } else {
++                                      strcpy(remcomOutBuffer, "OK");
++                              }
++
++                              ptr = 0;
++                      }
++                      if (ptr) {
++                              strcpy(remcomOutBuffer, "E02");
++                              debug_error
++                                  ("malformed write memory command: %s\n",
++                                   remcomInBuffer);
++                      }
++                      break;
++
++                      /* cAA..AA  Continue at address AA..AA(optional) */
++                      /* sAA..AA  Step one instruction from AA..AA(optional) */
++                      /* D        detach, reply OK and then continue */
++              case 'c':
++              case 's':
++              case 'D':
++
++                      /* try to read optional parameter, 
++                         pc unchanged if no parm */
++                      ptr = &remcomInBuffer[1];
++                      if (hexToInt(&ptr, &addr)) {
++                              if (remote_debug)
++                                      printk("Changing EIP to 0x%x\n", addr);
++
++                              regs.eip = addr;
++                      }
++
++                      newPC = regs.eip;
++
++                      /* clear the trace bit */
++                      regs.eflags &= 0xfffffeff;
++
++                      /* set the trace bit if we're stepping */
++                      if (remcomInBuffer[0] == 's')
++                              regs.eflags |= 0x100;
++
++                      /* detach is a friendly version of continue. Note that
++                         debugging is still enabled (e.g hit control C)
++                         until the process that issued an ioctl TIOCGDB
++                         terminates
++                       */
++                      if (remcomInBuffer[0] == 'D') {
++                              strcpy(remcomOutBuffer, "OK");
++                              putpacket(remcomOutBuffer);
++                      }
++
++                      if (remote_debug) {
++                              printk("Resuming execution\n");
++                              print_regs(&regs);
++                      }
++                      asm volatile ("movl %%db6, %0\n":"=r" (dr6)
++                                    :);
++                      if (!(dr6 & 0x4000)) {
++                              for (breakno = 0; breakno < 4; ++breakno) {
++                                      if (dr6 & (1 << breakno) &&
++                                          (breakinfo[breakno].type == 0)) {
++                                              /* Set restore flag */
++                                              regs.eflags |= 0x10000;
++                                              break;
++                                      }
++                              }
++                      }
++                      correct_hw_break();
++                      asm volatile ("movl %0, %%db6\n"::"r" (0));
++                      goto exit_kgdb;
++
++                      /* kill the program */
++              case 'k':       /* do nothing */
++                      break;
++
++                      /* query */
++              case 'q':
++                      switch (remcomInBuffer[1]) {
++                      case 'L':
++                              /* List threads */
++                              thread_list = 2;
++                              thread_list_start = (usethread ? : current);
++                              unpack_byte(remcomInBuffer + 3, &maxthreads);
++                              unpack_threadid(remcomInBuffer + 5, &thref);
++                              do {
++                                      int buf_thread_limit =
++                                          (BUFMAX - 22) / BUF_THREAD_ID_SIZE;
++                                      if (maxthreads > buf_thread_limit) {
++                                              maxthreads = buf_thread_limit;
++                                      }
++                              } while (0);
++                              remcomOutBuffer[0] = 'q';
++                              remcomOutBuffer[1] = 'M';
++                              remcomOutBuffer[4] = '0';
++                              pack_threadid(remcomOutBuffer + 5, &thref);
++
++                              threadid = threadref_to_int(&thref);
++                              for (nothreads = 0;
++                                   nothreads < maxthreads &&
++                                   threadid < PID_MAX + MAX_NO_CPUS;
++                                   threadid++) {
++                                      thread = getthread(threadid);
++                                      if (thread) {
++                                              int_to_threadref(&thref,
++                                                               threadid);
++                                              pack_threadid(remcomOutBuffer +
++                                                            21 +
++                                                            nothreads * 16,
++                                                            &thref);
++                                              nothreads++;
++                                              if (thread_min > threadid)
++                                                      thread_min = threadid;
++                                      }
++                              }
++
++                              if (threadid == PID_MAX + MAX_NO_CPUS) {
++                                      remcomOutBuffer[4] = '1';
++                              }
++                              pack_hex_byte(remcomOutBuffer + 2, nothreads);
++                              remcomOutBuffer[21 + nothreads * 16] = '\0';
++                              break;
++
++                      case 'C':
++                              /* Current thread id */
++                              remcomOutBuffer[0] = 'Q';
++                              remcomOutBuffer[1] = 'C';
++                              threadid = current->pid;
++                              if (!threadid) {
++                                      /*
++                                       * idle thread
++                                       */
++                                      for (threadid = PID_MAX;
++                                           threadid < PID_MAX + MAX_NO_CPUS;
++                                           threadid++) {
++                                              if (current ==
++                                                  idle_task(threadid -
++                                                            PID_MAX))
++                                                      break;
++                                      }
++                              }
++                              int_to_threadref(&thref, threadid);
++                              pack_threadid(remcomOutBuffer + 2, &thref);
++                              remcomOutBuffer[18] = '\0';
++                              break;
++
++                      case 'E':
++                              /* Print exception info */
++                              printexceptioninfo(exceptionVector,
++                                                 err_code, remcomOutBuffer);
++                              break;
++                      }
++                      break;
++
++                      /* task related */
++              case 'H':
++                      switch (remcomInBuffer[1]) {
++                      case 'g':
++                              ptr = &remcomInBuffer[2];
++                              hexToInt(&ptr, &threadid);
++                              thread = getthread(threadid);
++                              if (!thread) {
++                                      remcomOutBuffer[0] = 'E';
++                                      remcomOutBuffer[1] = '\0';
++                                      break;
++                              }
++                              /*
++                               * Just in case I forget what this is all about,
++                               * the "thread info" command to gdb causes it
++                               * to ask for a thread list.  It then switches
++                               * to each thread and asks for the registers.
++                               * For this (and only this) usage, we want to
++                               * fudge the registers of tasks not on the run
++                               * list (i.e. waiting) to show the routine that
++                               * called schedule. Also, gdb, is a minimalist
++                               * in that if the current thread is the last
++                               * it will not re-read the info when done.
++                               * This means that in this case we must show
++                               * the real registers. So here is how we do it:
++                               * Each entry we keep track of the min
++                               * thread in the list (the last that gdb will)
++                               * get info for.  We also keep track of the
++                               * starting thread.
++                               * "thread_list" is cleared when switching back
++                               * to the min thread if it is was current, or
++                               * if it was not current, thread_list is set 
++                               * to 1.  When the switch to current comes,
++                               * if thread_list is 1, clear it, else do 
++                               * nothing.
++                               */
++                              usethread = thread;
++                              if ((thread_list == 1) &&
++                                  (thread == thread_list_start)) {
++                                      thread_list = 0;
++                              }
++                              if (thread_list && (threadid == thread_min)) {
++                                      if (thread == thread_list_start) {
++                                              thread_list = 0;
++                                      } else {
++                                              thread_list = 1;
++                                      }
++                              }
++                              /* follow through */
++                      case 'c':
++                              remcomOutBuffer[0] = 'O';
++                              remcomOutBuffer[1] = 'K';
++                              remcomOutBuffer[2] = '\0';
++                              break;
++                      }
++                      break;
++
++                      /* Query thread status */
++              case 'T':
++                      ptr = &remcomInBuffer[1];
++                      hexToInt(&ptr, &threadid);
++                      thread = getthread(threadid);
++                      if (thread) {
++                              remcomOutBuffer[0] = 'O';
++                              remcomOutBuffer[1] = 'K';
++                              remcomOutBuffer[2] = '\0';
++                              if (thread_min > threadid)
++                                      thread_min = threadid;
++                      } else {
++                              remcomOutBuffer[0] = 'E';
++                              remcomOutBuffer[1] = '\0';
++                      }
++                      break;
++
++              case 'Y':
++                      ptr = &remcomInBuffer[1];
++                      hexToInt(&ptr, &breakno);
++                      ptr++;
++                      hexToInt(&ptr, &breaktype);
++                      ptr++;
++                      hexToInt(&ptr, &length);
++                      ptr++;
++                      hexToInt(&ptr, &addr);
++                      if (set_hw_break(breakno & 0x3,
++                                       breaktype & 0x3,
++                                       length & 0x3, addr) == 0) {
++                              strcpy(remcomOutBuffer, "OK");
++                      } else {
++                              strcpy(remcomOutBuffer, "ERROR");
++                      }
++                      break;
++
++                      /* Remove hardware breakpoint */
++              case 'y':
++                      ptr = &remcomInBuffer[1];
++                      hexToInt(&ptr, &breakno);
++                      if (remove_hw_break(breakno & 0x3) == 0) {
++                              strcpy(remcomOutBuffer, "OK");
++                      } else {
++                              strcpy(remcomOutBuffer, "ERROR");
++                      }
++                      break;
++
++              case 'r':       /* reboot */
++                      strcpy(remcomOutBuffer, "OK");
++                      putpacket(remcomOutBuffer);
++                      /*to_gdb("Rebooting\n"); */
++                      /* triplefault   no return from here */
++                      {
++                              static long no_idt[2];
++                              __asm__ __volatile__("lidt %0"::"m"(no_idt));
++                              BREAKPOINT;
++                      }
++
++              }               /* switch */
++
++              /* reply to the request */
++              putpacket(remcomOutBuffer);
++      }                       /* while(1==1) */
++      /*
++       *  reached by goto only.
++       */
++      exit_kgdb:
++      /*
++       * Here is where we set up to trap a gdb function call.  NEW_esp
++       * will be changed if we are trying to do this.  We handle both
++       * adding and subtracting, thus allowing gdb to put grung on 
++       * the stack which it removes later.
++       */
++      if (NEW_esp != OLD_esp) {
++              int *ptr = END_OF_LOOKASIDE;
++              if (NEW_esp < OLD_esp)
++                      ptr -= (OLD_esp - NEW_esp) / sizeof (int);
++              *--ptr = linux_regs->eflags;
++              *--ptr = linux_regs->xcs;
++              *--ptr = linux_regs->eip;
++              *--ptr = linux_regs->ecx;
++              *--ptr = linux_regs->ebx;
++              *--ptr = linux_regs->eax;
++              linux_regs->ecx = NEW_esp - (sizeof (int) * 6);
++              linux_regs->ebx = (unsigned int) END_OF_LOOKASIDE;
++              if (NEW_esp < OLD_esp) {
++                      linux_regs->eip = (unsigned int) fn_call_stub;
++              } else {
++                      linux_regs->eip = (unsigned int) fn_rtn_stub;
++                      linux_regs->eax = NEW_esp;
++              }
++              linux_regs->eflags &= ~(IF_BIT | TF_BIT);
++      }
++#ifdef CONFIG_SMP
++      /*
++       * Release gdb wait locks 
++       * Sanity check time.  Must have at least one cpu to run.  Also single
++       * step must not be done if the current cpu is on hold.
++       */
++      if (spinlock_count == 1) {
++              int ss_hold = (regs.eflags & 0x100) && kgdb_info.hold_on_sstep;
++              int cpu_avail = 0;
++              int i;
++
++              for (i = 0; i < MAX_NO_CPUS; i++) {
++                      if (!cpu_online(i))
++                              break;
++                      if (!hold_cpu(i)) {
++                              cpu_avail = 1;
++                      }
++              }
++              /*
++               * Early in the bring up there will be NO cpus on line...
++               */
++              if (!cpu_avail && !cpus_empty(cpu_online_map)) {
++                      to_gdb("No cpus unblocked, see 'kgdb_info.hold_cpu'\n");
++                      goto once_again;
++              }
++              if (hold_cpu(smp_processor_id()) && (regs.eflags & 0x100)) {
++                      to_gdb
++                          ("Current cpu must be unblocked to single step\n");
++                      goto once_again;
++              }
++              if (!(ss_hold)) {
++                      int i;
++                      for (i = 0; i < MAX_NO_CPUS; i++) {
++                              if (!hold_cpu(i)) {
++                                      spin_unlock(&waitlocks[i]);
++                              }
++                      }
++              } else {
++                      spin_unlock(&waitlocks[smp_processor_id()]);
++              }
++              /* Release kgdb spinlock */
++              KGDB_SPIN_UNLOCK(&kgdb_spinlock);
++              /*
++               * If this cpu is on hold, this is where we
++               * do it.  Note, the NMI will pull us out of here,
++               * but will return as the above lock is not held.
++               * We will stay here till another cpu releases the lock for us.
++               */
++              spin_unlock_wait(waitlocks + smp_processor_id());
++              kgdb_local_irq_restore(flags);
++              return (0);
++      }
++#if 0
++exit_just_unlock:
++#endif
++#endif
++      /* Release kgdb spinlock */
++      KGDB_SPIN_UNLOCK(&kgdb_spinlock);
++      kgdb_local_irq_restore(flags);
++      return (0);
++}
++
++/* this function is used to set up exception handlers for tracing and
++ * breakpoints. 
++ * This function is not needed as the above line does all that is needed.
++ * We leave it for backward compatitability...
++ */
++void
++set_debug_traps(void)
++{
++      /*
++       * linux_debug_hook is defined in traps.c.  We store a pointer
++       * to our own exception handler into it.
++
++       * But really folks, every hear of labeled common, an old Fortran
++       * concept.  Lots of folks can reference it and it is define if 
++       * anyone does.  Only one can initialize it at link time.  We do 
++       * this with the hook.  See the statement above.  No need for any
++       * executable code and it is ready as soon as the kernel is
++       * loaded.  Very desirable in kernel debugging.
++
++       linux_debug_hook = handle_exception ;
++       */
++
++      /* In case GDB is started before us, ack any packets (presumably
++         "$?#xx") sitting there. 
++         putDebugChar ('+');
++
++         initialized = 1;
++       */
++}
++
++/* This function will generate a breakpoint exception.        It is used at the
++   beginning of a program to sync up with a debugger and can be used
++   otherwise as a quick means to stop program execution and "break" into
++   the debugger. */
++/* But really, just use the BREAKPOINT macro.  We will handle the int stuff
++ */
++
++#ifdef later
++/*
++ * possibly we should not go thru the traps.c code at all?  Someday.
++ */
++void
++do_kgdb_int3(struct pt_regs *regs, long error_code)
++{
++      kgdb_handle_exception(3, 5, error_code, regs);
++      return;
++}
++#endif
++#undef regs
++#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
++asmlinkage void
++bad_sys_call_exit(int stuff)
++{
++      struct pt_regs *regs = (struct pt_regs *) &stuff;
++      printk("Sys call %d return with %x preempt_count\n",
++             (int) regs->orig_eax, preempt_count());
++}
++#endif
++#ifdef CONFIG_STACK_OVERFLOW_TEST
++#include <asm/kgdb.h>
++asmlinkage void
++stack_overflow(void)
++{
++#ifdef BREAKPOINT
++      BREAKPOINT;
++#else
++      printk("Kernel stack overflow, looping forever\n");
++#endif
++      while (1) {
++      }
++}
++#endif
++
++#if defined(CONFIG_SMP) || defined(CONFIG_KGDB_CONSOLE)
++char gdbconbuf[BUFMAX];
++
++static void
++kgdb_gdb_message(const char *s, unsigned count)
++{
++      int i;
++      int wcount;
++      char *bufptr;
++      /*
++       * This takes care of NMI while spining out chars to gdb
++       */
++      IF_SMP(in_kgdb_console = 1);
++      gdbconbuf[0] = 'O';
++      bufptr = gdbconbuf + 1;
++      while (count > 0) {
++              if ((count << 1) > (BUFMAX - 2)) {
++                      wcount = (BUFMAX - 2) >> 1;
++              } else {
++                      wcount = count;
++              }
++              count -= wcount;
++              for (i = 0; i < wcount; i++) {
++                      bufptr = pack_hex_byte(bufptr, s[i]);
++              }
++              *bufptr = '\0';
++              s += wcount;
++
++              putpacket(gdbconbuf);
++
++      }
++      IF_SMP(in_kgdb_console = 0);
++}
++#endif
++#ifdef CONFIG_SMP
++static void
++to_gdb(const char *s)
++{
++      int count = 0;
++      while (s[count] && (count++ < BUFMAX)) ;
++      kgdb_gdb_message(s, count);
++}
++#endif
++#ifdef CONFIG_KGDB_CONSOLE
++#include <linux/console.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <asm/uaccess.h>
++#include <asm/semaphore.h>
++
++void
++kgdb_console_write(struct console *co, const char *s, unsigned count)
++{
++
++      if (gdb_i386vector == -1) {
++              /*
++               * We have not yet talked to gdb.  What to do...
++               * lets break, on continue we can do the write.
++               * But first tell him whats up. Uh, well no can do,
++               * as this IS the console.  Oh well...
++               * We do need to wait or the messages will be lost.
++               * Other option would be to tell the above code to
++               * ignore this breakpoint and do an auto return, 
++               * but that might confuse gdb.  Also this happens 
++               * early enough in boot up that we don't have the traps
++               * set up yet, so...
++               */
++              breakpoint();
++      }
++      kgdb_gdb_message(s, count);
++}
++
++/*
++ * ------------------------------------------------------------
++ * Serial KGDB driver 
++ * ------------------------------------------------------------
++ */
++
++static struct console kgdbcons = {
++      name:"kgdb",
++      write:kgdb_console_write,
++#ifdef CONFIG_KGDB_USER_CONSOLE
++      device:kgdb_console_device,
++#endif
++      flags:CON_PRINTBUFFER | CON_ENABLED,
++      index:-1,
++};
++
++/*
++ * The trick here is that this file gets linked before printk.o
++ * That means we get to peer at the console info in the command
++ * line before it does.        If we are up, we register, otherwise,
++ * do nothing.        By returning 0, we allow printk to look also.
++ */
++static int kgdb_console_enabled;
++
++int __init
++kgdb_console_init(char *str)
++{
++      if ((strncmp(str, "kgdb", 4) == 0) || (strncmp(str, "gdb", 3) == 0)) {
++              register_console(&kgdbcons);
++              kgdb_console_enabled = 1;
++      }
++      return 0;               /* let others look at the string */
++}
++
++__setup("console=", kgdb_console_init);
++
++#ifdef CONFIG_KGDB_USER_CONSOLE
++static kdev_t kgdb_console_device(struct console *c);
++/* This stuff sort of works, but it knocks out telnet devices  
++ * we are leaving it here in case we (or you) find time to figure it out
++ * better..
++ */
++
++/*
++ * We need a real char device as well for when the console is opened for user
++ * space activities.
++ */
++
++static int
++kgdb_consdev_open(struct inode *inode, struct file *file)
++{
++      return 0;
++}
++
++static ssize_t
++kgdb_consdev_write(struct file *file, const char *buf,
++                 size_t count, loff_t * ppos)
++{
++      int size, ret = 0;
++      static char kbuf[128];
++      static DECLARE_MUTEX(sem);
++
++      /* We are not reentrant... */
++      if (down_interruptible(&sem))
++              return -ERESTARTSYS;
++
++      while (count > 0) {
++              /* need to copy the data from user space */
++              size = count;
++              if (size > sizeof (kbuf))
++                      size = sizeof (kbuf);
++              if (copy_from_user(kbuf, buf, size)) {
++                      ret = -EFAULT;
++                      break;;
++              }
++              kgdb_console_write(&kgdbcons, kbuf, size);
++              count -= size;
++              ret += size;
++              buf += size;
++      }
++
++      up(&sem);
++
++      return ret;
++}
++
++struct file_operations kgdb_consdev_fops = {
++      open:kgdb_consdev_open,
++      write:kgdb_consdev_write
++};
++static kdev_t
++kgdb_console_device(struct console *c)
++{
++      return MKDEV(TTYAUX_MAJOR, 1);
++}
++
++/*
++ * This routine gets called from the serial stub in the i386/lib 
++ * This is so it is done late in bring up (just before the console open).
++ */
++void
++kgdb_console_finit(void)
++{
++      if (kgdb_console_enabled) {
++              char *cptr = cdevname(MKDEV(TTYAUX_MAJOR, 1));
++              char *cp = cptr;
++              while (*cptr && *cptr != '(')
++                      cptr++;
++              *cptr = 0;
++              unregister_chrdev(TTYAUX_MAJOR, cp);
++              register_chrdev(TTYAUX_MAJOR, "kgdb", &kgdb_consdev_fops);
++      }
++}
++#endif
++#endif
++#ifdef CONFIG_KGDB_TS
++#include <asm/msr.h>          /* time stamp code */
++#include <asm/hardirq.h>      /* in_interrupt */
++#ifdef CONFIG_KGDB_TS_64
++#define DATA_POINTS 64
++#endif
++#ifdef CONFIG_KGDB_TS_128
++#define DATA_POINTS 128
++#endif
++#ifdef CONFIG_KGDB_TS_256
++#define DATA_POINTS 256
++#endif
++#ifdef CONFIG_KGDB_TS_512
++#define DATA_POINTS 512
++#endif
++#ifdef CONFIG_KGDB_TS_1024
++#define DATA_POINTS 1024
++#endif
++#ifndef DATA_POINTS
++#define DATA_POINTS 128               /* must be a power of two */
++#endif
++#define INDEX_MASK (DATA_POINTS - 1)
++#if (INDEX_MASK & DATA_POINTS)
++#error "CONFIG_KGDB_TS_COUNT must be a power of 2"
++#endif
++struct kgdb_and_then_struct {
++#ifdef CONFIG_SMP
++      int on_cpu;
++#endif
++      struct task_struct *task;
++      long long at_time;
++      int from_ln;
++      char *in_src;
++      void *from;
++      int *with_shpf;
++      int data0;
++      int data1;
++};
++struct kgdb_and_then_struct2 {
++#ifdef CONFIG_SMP
++      int on_cpu;
++#endif
++      struct task_struct *task;
++      long long at_time;
++      int from_ln;
++      char *in_src;
++      void *from;
++      int *with_shpf;
++      struct task_struct *t1;
++      struct task_struct *t2;
++};
++struct kgdb_and_then_struct kgdb_data[DATA_POINTS];
++
++struct kgdb_and_then_struct *kgdb_and_then = &kgdb_data[0];
++int kgdb_and_then_count;
++
++void
++kgdb_tstamp(int line, char *source, int data0, int data1)
++{
++      static spinlock_t ts_spin = SPIN_LOCK_UNLOCKED;
++      int flags;
++      kgdb_local_irq_save(flags);
++      spin_lock(&ts_spin);
++      rdtscll(kgdb_and_then->at_time);
++#ifdef CONFIG_SMP
++      kgdb_and_then->on_cpu = smp_processor_id();
++#endif
++      kgdb_and_then->task = current;
++      kgdb_and_then->from_ln = line;
++      kgdb_and_then->in_src = source;
++      kgdb_and_then->from = __builtin_return_address(0);
++      kgdb_and_then->with_shpf = (int *) (((flags & IF_BIT) >> 9) |
++                                          (preempt_count() << 8));
++      kgdb_and_then->data0 = data0;
++      kgdb_and_then->data1 = data1;
++      kgdb_and_then = &kgdb_data[++kgdb_and_then_count & INDEX_MASK];
++      spin_unlock(&ts_spin);
++      kgdb_local_irq_restore(flags);
++#ifdef CONFIG_PREEMPT
++
++#endif
++      return;
++}
++#endif
++typedef int gdb_debug_hook(int exceptionVector,
++                         int signo, int err_code, struct pt_regs *linux_regs);
++gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;    /* histerical reasons... */
+--- linux-2.6.0-test1/arch/i386/kernel/ldt.c   2003-06-14 12:18:25.000000000 -0700
++++ 25/arch/i386/kernel/ldt.c  2003-07-19 17:04:06.000000000 -0700
+@@ -56,9 +56,11 @@ static int alloc_ldt(mm_context_t *pc, i
+       if (reload) {
+ #ifdef CONFIG_SMP
++              cpumask_t mask;
+               preempt_disable();
+               load_LDT(pc);
+-              if (current->mm->cpu_vm_mask != (1 << smp_processor_id()))
++              mask = cpumask_of_cpu(smp_processor_id());
++              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
+                       smp_call_function(flush_ldt, 0, 1, 1);
+               preempt_enable();
+ #else
+--- linux-2.6.0-test1/arch/i386/kernel/Makefile        2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/i386/kernel/Makefile       2003-07-19 17:04:02.000000000 -0700
+@@ -14,6 +14,7 @@ obj-y                                += timers/
+ obj-$(CONFIG_ACPI)            += acpi/
+ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
+ obj-$(CONFIG_MCA)             += mca.o
++obj-$(CONFIG_KGDB)            += kgdb_stub.o 
+ obj-$(CONFIG_X86_MSR)         += msr.o
+ obj-$(CONFIG_X86_CPUID)               += cpuid.o
+ obj-$(CONFIG_MICROCODE)               += microcode.o
+--- linux-2.6.0-test1/arch/i386/kernel/mpparse.c       2003-06-16 22:32:20.000000000 -0700
++++ 25/arch/i386/kernel/mpparse.c      2003-07-19 17:04:06.000000000 -0700
+@@ -71,7 +71,7 @@ unsigned int boot_cpu_logical_apicid = -
+ static unsigned int __initdata num_processors;
+ /* Bitmask of physically existing CPUs */
+-unsigned long phys_cpu_present_map;
++physid_mask_t phys_cpu_present_map;
+ u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+@@ -106,6 +106,7 @@ static struct mpc_config_translation *tr
+ void __init MP_processor_info (struct mpc_config_processor *m)
+ {
+       int ver, apicid;
++      physid_mask_t tmp;
+       
+       if (!(m->mpc_cpuflag & CPU_ENABLED))
+               return;
+@@ -176,7 +177,8 @@ void __init MP_processor_info (struct mp
+       }
+       ver = m->mpc_apicver;
+-      phys_cpu_present_map |= apicid_to_cpu_present(apicid);
++      tmp = apicid_to_cpu_present(apicid);
++      physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp);
+       
+       /*
+        * Validate version
+--- linux-2.6.0-test1/arch/i386/kernel/msr.c   2003-06-14 12:18:08.000000000 -0700
++++ 25/arch/i386/kernel/msr.c  2003-07-19 17:04:06.000000000 -0700
+@@ -242,7 +242,7 @@ static int msr_open(struct inode *inode,
+   int cpu = minor(file->f_dentry->d_inode->i_rdev);
+   struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+   
+-  if ( !(cpu_online_map & (1UL << cpu)) )
++  if (!cpu_online(cpu))
+     return -ENXIO;            /* No such CPU */
+   if ( !cpu_has(c, X86_FEATURE_MSR) )
+     return -EIO;              /* MSR not supported */
+--- linux-2.6.0-test1/arch/i386/kernel/nmi.c   2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/i386/kernel/nmi.c  2003-07-19 17:04:02.000000000 -0700
+@@ -31,7 +31,17 @@
+ #include <asm/mpspec.h>
+ #include <asm/nmi.h>
++#ifdef CONFIG_KGDB
++#include <asm/kgdb.h>
++#ifdef CONFIG_SMP
++unsigned int nmi_watchdog = NMI_IO_APIC;
++#else
++unsigned int nmi_watchdog = NMI_LOCAL_APIC;
++#endif
++#else
+ unsigned int nmi_watchdog = NMI_NONE;
++#endif
++
+ static unsigned int nmi_hz = HZ;
+ unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */
+ extern void show_registers(struct pt_regs *regs);
+@@ -396,6 +406,9 @@ void touch_nmi_watchdog (void)
+       for (i = 0; i < NR_CPUS; i++)
+               alert_counter[i] = 0;
+ }
++#ifdef CONFIG_KGDB
++int tune_watchdog = 5*HZ;
++#endif
+ void nmi_watchdog_tick (struct pt_regs * regs)
+ {
+@@ -409,12 +422,24 @@ void nmi_watchdog_tick (struct pt_regs *
+       sum = irq_stat[cpu].apic_timer_irqs;
++#ifdef CONFIG_KGDB
++      if (! in_kgdb(regs) && last_irq_sums[cpu] == sum ) {
++  
++#else
+       if (last_irq_sums[cpu] == sum) {
++#endif
+               /*
+                * Ayiee, looks like this CPU is stuck ...
+                * wait a few IRQs (5 seconds) before doing the oops ...
+                */
+               alert_counter[cpu]++;
++#ifdef CONFIG_KGDB
++                if (alert_counter[cpu] == tune_watchdog) {                      
++                        kgdb_handle_exception(2, SIGPWR, 0, regs);
++                        last_irq_sums[cpu] = sum;
++                        alert_counter[cpu] = 0;
++                }
++#endif
+               if (alert_counter[cpu] == 5*nmi_hz) {
+                       spin_lock(&nmi_print_lock);
+                       /*
+--- linux-2.6.0-test1/arch/i386/kernel/reboot.c        2003-06-14 12:18:06.000000000 -0700
++++ 25/arch/i386/kernel/reboot.c       2003-07-19 17:04:06.000000000 -0700
+@@ -226,7 +226,7 @@ void machine_restart(char * __unused)
+                  if its not, default to the BSP */
+               if ((reboot_cpu == -1) ||  
+                     (reboot_cpu > (NR_CPUS -1))  || 
+-                    !(phys_cpu_present_map & (1<<cpuid))) 
++                    !cpu_isset(cpuid, phys_cpu_present_map))
+                       reboot_cpu = boot_cpu_physical_apicid;
+               reboot_smp = 0;  /* use this as a flag to only go through this once*/
+--- linux-2.6.0-test1/arch/i386/kernel/setup.c 2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/i386/kernel/setup.c        2003-07-19 17:03:49.000000000 -0700
+@@ -42,6 +42,7 @@
+ #include <asm/edd.h>
+ #include <asm/setup.h>
+ #include <asm/arch_hooks.h>
++#include <asm/sections.h>
+ #include "setup_arch_pre.h"
+ #include "mach_resources.h"
+@@ -100,7 +101,7 @@ extern void early_cpu_init(void);
+ extern void dmi_scan_machine(void);
+ extern void generic_apic_probe(char *);
+ extern int root_mountflags;
+-extern char _text, _etext, _edata, _end;
++extern char _end[];
+ unsigned long saved_videomode;
+@@ -520,7 +521,7 @@ static void __init parse_cmdline_early (
+                       acpi_disabled = 1;
+               /* "acpismp=force" turns on ACPI again */
+-              else if (!memcmp(from, "acpismp=force", 14))
++              if (c == ' ' && !memcmp(from, "acpismp=force", 13))
+                       acpi_disabled = 0;
+               /*
+@@ -676,7 +677,7 @@ static unsigned long __init setup_memory
+        * partially used pages are not usable - thus
+        * we are rounding upwards:
+        */
+-      start_pfn = PFN_UP(__pa(&_end));
++      start_pfn = PFN_UP(__pa(_end));
+       find_max_pfn();
+@@ -947,15 +948,15 @@ void __init setup_arch(char **cmdline_p)
+       if (!MOUNT_ROOT_RDONLY)
+               root_mountflags &= ~MS_RDONLY;
+-      init_mm.start_code = (unsigned long) &_text;
+-      init_mm.end_code = (unsigned long) &_etext;
+-      init_mm.end_data = (unsigned long) &_edata;
+-      init_mm.brk = (unsigned long) &_end;
+-
+-      code_resource.start = virt_to_phys(&_text);
+-      code_resource.end = virt_to_phys(&_etext)-1;
+-      data_resource.start = virt_to_phys(&_etext);
+-      data_resource.end = virt_to_phys(&_edata)-1;
++      init_mm.start_code = (unsigned long) _text;
++      init_mm.end_code = (unsigned long) _etext;
++      init_mm.end_data = (unsigned long) _edata;
++      init_mm.brk = (unsigned long) _end;
++
++      code_resource.start = virt_to_phys(_text);
++      code_resource.end = virt_to_phys(_etext)-1;
++      data_resource.start = virt_to_phys(_etext);
++      data_resource.end = virt_to_phys(_edata)-1;
+       parse_cmdline_early(cmdline_p);
+@@ -977,7 +978,7 @@ void __init setup_arch(char **cmdline_p)
+       generic_apic_probe(*cmdline_p);
+ #endif        
+-#ifdef CONFIG_ACPI_BOOT
++#ifdef CONFIG_ACPI
+       /*
+        * Parse the ACPI tables for possible boot-time SMP configuration.
+        */
+--- linux-2.6.0-test1/arch/i386/kernel/smpboot.c       2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/kernel/smpboot.c      2003-07-19 17:04:06.000000000 -0700
+@@ -61,12 +61,12 @@ static int __initdata smp_b_stepping;
+ int smp_num_siblings = 1;
+ int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+-/* Bitmask of currently online CPUs */
+-unsigned long cpu_online_map;
++/* bitmap of online cpus */
++cpumask_t cpu_online_map;
+-static volatile unsigned long cpu_callin_map;
+-volatile unsigned long cpu_callout_map;
+-static unsigned long smp_commenced_mask;
++static cpumask_t cpu_callin_map;
++cpumask_t cpu_callout_map;
++static cpumask_t smp_commenced_mask;
+ /* Per CPU bogomips and other parameters */
+ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
+@@ -268,7 +268,7 @@ static void __init synchronize_tsc_bp (v
+       sum = 0;
+       for (i = 0; i < NR_CPUS; i++) {
+-              if (test_bit(i, &cpu_callout_map)) {
++              if (cpu_isset(i, cpu_callout_map)) {
+                       t0 = tsc_values[i];
+                       sum += t0;
+               }
+@@ -277,7 +277,7 @@ static void __init synchronize_tsc_bp (v
+       sum = 0;
+       for (i = 0; i < NR_CPUS; i++) {
+-              if (!test_bit(i, &cpu_callout_map))
++              if (!cpu_isset(i, cpu_callout_map))
+                       continue;
+               delta = tsc_values[i] - avg;
+               if (delta < 0)
+@@ -353,7 +353,7 @@ void __init smp_callin(void)
+        */
+       phys_id = GET_APIC_ID(apic_read(APIC_ID));
+       cpuid = smp_processor_id();
+-      if (test_bit(cpuid, &cpu_callin_map)) {
++      if (cpu_isset(cpuid, cpu_callin_map)) {
+               printk("huh, phys CPU#%d, CPU#%d already present??\n",
+                                       phys_id, cpuid);
+               BUG();
+@@ -376,7 +376,7 @@ void __init smp_callin(void)
+               /*
+                * Has the boot CPU finished it's STARTUP sequence?
+                */
+-              if (test_bit(cpuid, &cpu_callout_map))
++              if (cpu_isset(cpuid, cpu_callout_map))
+                       break;
+               rep_nop();
+       }
+@@ -417,7 +417,7 @@ void __init smp_callin(void)
+       /*
+        * Allow the master to continue.
+        */
+-      set_bit(cpuid, &cpu_callin_map);
++      cpu_set(cpuid, cpu_callin_map);
+       /*
+        *      Synchronize the TSC with the BP
+@@ -442,7 +442,7 @@ int __init start_secondary(void *unused)
+        */
+       cpu_init();
+       smp_callin();
+-      while (!test_bit(smp_processor_id(), &smp_commenced_mask))
++      while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
+               rep_nop();
+       setup_secondary_APIC_clock();
+       if (nmi_watchdog == NMI_IO_APIC) {
+@@ -456,7 +456,7 @@ int __init start_secondary(void *unused)
+        * the local TLBs too.
+        */
+       local_flush_tlb();
+-      set_bit(smp_processor_id(), &cpu_online_map);
++      cpu_set(smp_processor_id(), cpu_online_map);
+       wmb();
+       return cpu_idle();
+ }
+@@ -499,16 +499,16 @@ static struct task_struct * __init fork_
+ #ifdef CONFIG_NUMA
+ /* which logical CPUs are on which nodes */
+-volatile unsigned long node_2_cpu_mask[MAX_NR_NODES] = 
+-                                              { [0 ... MAX_NR_NODES-1] = 0 };
++cpumask_t node_2_cpu_mask[MAX_NR_NODES] =
++                              { [0 ... MAX_NR_NODES-1] = CPU_MASK_NONE };
+ /* which node each logical CPU is on */
+-volatile int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
++int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
+ /* set up a mapping between cpu and node. */
+ static inline void map_cpu_to_node(int cpu, int node)
+ {
+       printk("Mapping cpu %d to node %d\n", cpu, node);
+-      node_2_cpu_mask[node] |= (1 << cpu);
++      cpu_set(cpu, node_2_cpu_mask[node]);
+       cpu_2_node[cpu] = node;
+ }
+@@ -519,7 +519,7 @@ static inline void unmap_cpu_to_node(int
+       printk("Unmapping cpu %d from all nodes\n", cpu);
+       for (node = 0; node < MAX_NR_NODES; node ++)
+-              node_2_cpu_mask[node] &= ~(1 << cpu);
++              cpu_clear(cpu, node_2_cpu_mask[node]);
+       cpu_2_node[cpu] = -1;
+ }
+ #else /* !CONFIG_NUMA */
+@@ -529,7 +529,7 @@ static inline void unmap_cpu_to_node(int
+ #endif /* CONFIG_NUMA */
+-volatile u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
++u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+ void map_cpu_to_logical_apicid(void)
+ {
+@@ -770,7 +770,7 @@ wakeup_secondary_cpu(int phys_apicid, un
+ }
+ #endif        /* WAKE_SECONDARY_VIA_INIT */
+-extern unsigned long cpu_initialized;
++extern cpumask_t cpu_initialized;
+ static int __init do_boot_cpu(int apicid)
+ /*
+@@ -836,19 +836,19 @@ static int __init do_boot_cpu(int apicid
+                * allow APs to start initializing.
+                */
+               Dprintk("Before Callout %d.\n", cpu);
+-              set_bit(cpu, &cpu_callout_map);
++              cpu_set(cpu, cpu_callout_map);
+               Dprintk("After Callout %d.\n", cpu);
+               /*
+                * Wait 5s total for a response
+                */
+               for (timeout = 0; timeout < 50000; timeout++) {
+-                      if (test_bit(cpu, &cpu_callin_map))
++                      if (cpu_isset(cpu, cpu_callin_map))
+                               break;  /* It has booted */
+                       udelay(100);
+               }
+-              if (test_bit(cpu, &cpu_callin_map)) {
++              if (cpu_isset(cpu, cpu_callin_map)) {
+                       /* number CPUs logically, starting from 1 (BSP is 0) */
+                       Dprintk("OK.\n");
+                       printk("CPU%d: ", cpu);
+@@ -869,8 +869,8 @@ static int __init do_boot_cpu(int apicid
+       if (boot_error) {
+               /* Try to put things back the way they were before ... */
+               unmap_cpu_to_logical_apicid(cpu);
+-              clear_bit(cpu, &cpu_callout_map); /* was set here (do_boot_cpu()) */
+-              clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
++              cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
++              cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
+               cpucount--;
+       }
+@@ -957,7 +957,7 @@ static void __init smp_boot_cpus(unsigne
+       if (!smp_found_config) {
+               printk(KERN_NOTICE "SMP motherboard not detected.\n");
+               smpboot_clear_io_apic_irqs();
+-              phys_cpu_present_map = 1;
++              phys_cpu_present_map = physid_mask_of_physid(0);
+               if (APIC_init_uniprocessor())
+                       printk(KERN_NOTICE "Local APIC not detected."
+                                          " Using dummy APIC emulation.\n");
+@@ -973,7 +973,7 @@ static void __init smp_boot_cpus(unsigne
+       if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
+               printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
+                               boot_cpu_physical_apicid);
+-              phys_cpu_present_map |= (1 << hard_smp_processor_id());
++              cpu_set(hard_smp_processor_id(), phys_cpu_present_map);
+       }
+       /*
+@@ -984,7 +984,7 @@ static void __init smp_boot_cpus(unsigne
+                       boot_cpu_physical_apicid);
+               printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
+               smpboot_clear_io_apic_irqs();
+-              phys_cpu_present_map = 1;
++              phys_cpu_present_map = physid_mask_of_physid(0);
+               return;
+       }
+@@ -997,7 +997,7 @@ static void __init smp_boot_cpus(unsigne
+               smp_found_config = 0;
+               printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
+               smpboot_clear_io_apic_irqs();
+-              phys_cpu_present_map = 1;
++              phys_cpu_present_map = physid_mask_of_physid(0);
+               return;
+       }
+@@ -1017,10 +1017,10 @@ static void __init smp_boot_cpus(unsigne
+        * bits 0-3 are quad0, 4-7 are quad1, etc. A perverse twist on the 
+        * clustered apic ID.
+        */
+-      Dprintk("CPU present map: %lx\n", phys_cpu_present_map);
++      Dprintk("CPU present map: %lx\n", cpus_coerce(phys_cpu_present_map));
+       kicked = 1;
+-      for (bit = 0; kicked < NR_CPUS && bit < BITS_PER_LONG; bit++) {
++      for (bit = 0; kicked < NR_CPUS && bit < MAX_APICS; bit++) {
+               apicid = cpu_present_to_apicid(bit);
+               /*
+                * Don't even attempt to start the boot CPU!
+@@ -1055,7 +1055,7 @@ static void __init smp_boot_cpus(unsigne
+       } else {
+               unsigned long bogosum = 0;
+               for (cpu = 0; cpu < NR_CPUS; cpu++)
+-                      if (cpu_callout_map & (1<<cpu))
++                      if (cpu_isset(cpu, cpu_callout_map))
+                               bogosum += cpu_data[cpu].loops_per_jiffy;
+               printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
+                       cpucount+1,
+@@ -1087,10 +1087,11 @@ static void __init smp_boot_cpus(unsigne
+               
+               for (cpu = 0; cpu < NR_CPUS; cpu++) {
+                       int     i;
+-                      if (!test_bit(cpu, &cpu_callout_map)) continue;
++                      if (!cpu_isset(cpu, cpu_callout_map))
++                              continue;
+                       for (i = 0; i < NR_CPUS; i++) {
+-                              if (i == cpu || !test_bit(i, &cpu_callout_map))
++                              if (i == cpu || !cpu_isset(i, cpu_callout_map))
+                                       continue;
+                               if (phys_proc_id[cpu] == phys_proc_id[i]) {
+                                       cpu_sibling_map[cpu] = i;
+@@ -1125,28 +1126,28 @@ void __init smp_prepare_cpus(unsigned in
+ void __devinit smp_prepare_boot_cpu(void)
+ {
+-      set_bit(smp_processor_id(), &cpu_online_map);
+-      set_bit(smp_processor_id(), &cpu_callout_map);
++      cpu_set(smp_processor_id(), cpu_online_map);
++      cpu_set(smp_processor_id(), cpu_callout_map);
+ }
+ int __devinit __cpu_up(unsigned int cpu)
+ {
+       /* This only works at boot for x86.  See "rewrite" above. */
+-      if (test_bit(cpu, &smp_commenced_mask)) {
++      if (cpu_isset(cpu, smp_commenced_mask)) {
+               local_irq_enable();
+               return -ENOSYS;
+       }
+       /* In case one didn't come up */
+-      if (!test_bit(cpu, &cpu_callin_map)) {
++      if (!cpu_isset(cpu, cpu_callin_map)) {
+               local_irq_enable();
+               return -EIO;
+       }
+       local_irq_enable();
+       /* Unleash the CPU! */
+-      set_bit(cpu, &smp_commenced_mask);
+-      while (!test_bit(cpu, &cpu_online_map))
++      cpu_set(cpu, smp_commenced_mask);
++      while (!cpu_isset(cpu, cpu_online_map))
+               mb();
+       return 0;
+ }
+@@ -1154,7 +1155,8 @@ int __devinit __cpu_up(unsigned int cpu)
+ void __init smp_cpus_done(unsigned int max_cpus)
+ {
+ #ifdef CONFIG_X86_IO_APIC
+-      setup_ioapic_dest(TARGET_CPUS);
++      cpumask_t targets = CPU_MASK_ALL;
++      setup_ioapic_dest(targets);
+ #endif
+       zap_low_mappings();
+ }
+--- linux-2.6.0-test1/arch/i386/kernel/smp.c   2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/kernel/smp.c  2003-07-19 17:04:06.000000000 -0700
+@@ -155,8 +155,12 @@ void send_IPI_self(int vector)
+       __send_IPI_shortcut(APIC_DEST_SELF, vector);
+ }
+-inline void send_IPI_mask_bitmask(int mask, int vector)
++/*
++ * This is only used on smaller machines.
++ */
++inline void send_IPI_mask_bitmask(cpumask_t cpumask, int vector)
+ {
++      unsigned long mask = cpus_coerce(cpumask);
+       unsigned long cfg;
+       unsigned long flags;
+@@ -186,10 +190,10 @@ inline void send_IPI_mask_bitmask(int ma
+       local_irq_restore(flags);
+ }
+-inline void send_IPI_mask_sequence(int mask, int vector)
++inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
+ {
+       unsigned long cfg, flags;
+-      unsigned int query_cpu, query_mask;
++      unsigned int query_cpu;
+       /*
+        * Hack. The clustered APIC addressing mode doesn't allow us to send 
+@@ -200,8 +204,7 @@ inline void send_IPI_mask_sequence(int m
+       local_irq_save(flags);
+       for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) {
+-              query_mask = 1 << query_cpu;
+-              if (query_mask & mask) {
++              if (cpu_isset(query_cpu, mask)) {
+               
+                       /*
+                        * Wait for idle.
+@@ -238,7 +241,7 @@ inline void send_IPI_mask_sequence(int m
+  *    Optimizations Manfred Spraul <manfred@colorfullife.com>
+  */
+-static volatile unsigned long flush_cpumask;
++static cpumask_t flush_cpumask;
+ static struct mm_struct * flush_mm;
+ static unsigned long flush_va;
+ static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
+@@ -255,7 +258,7 @@ static inline void leave_mm (unsigned lo
+ {
+       if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
+               BUG();
+-      clear_bit(cpu, &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
++      cpu_clear(cpu, cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
+       load_cr3(swapper_pg_dir);
+ }
+@@ -265,7 +268,7 @@ static inline void leave_mm (unsigned lo
+  * [cpu0: the cpu that switches]
+  * 1) switch_mm() either 1a) or 1b)
+  * 1a) thread switch to a different mm
+- * 1a1) clear_bit(cpu, &old_mm->cpu_vm_mask);
++ * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
+  *    Stop ipi delivery for the old mm. This is not synchronized with
+  *    the other cpus, but smp_invalidate_interrupt ignore flush ipis
+  *    for the wrong mm, and in the worst case we perform a superflous
+@@ -275,7 +278,7 @@ static inline void leave_mm (unsigned lo
+  *    was in lazy tlb mode.
+  * 1a3) update cpu_tlbstate[].active_mm
+  *    Now cpu0 accepts tlb flushes for the new mm.
+- * 1a4) set_bit(cpu, &new_mm->cpu_vm_mask);
++ * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
+  *    Now the other cpus will send tlb flush ipis.
+  * 1a4) change cr3.
+  * 1b) thread switch without mm change
+@@ -311,7 +314,7 @@ asmlinkage void smp_invalidate_interrupt
+       cpu = get_cpu();
+-      if (!test_bit(cpu, &flush_cpumask))
++      if (!cpu_isset(cpu, flush_cpumask))
+               goto out;
+               /* 
+                * This was a BUG() but until someone can quote me the
+@@ -332,15 +335,17 @@ asmlinkage void smp_invalidate_interrupt
+                       leave_mm(cpu);
+       }
+       ack_APIC_irq();
+-      clear_bit(cpu, &flush_cpumask);
+-
++      smp_mb__before_clear_bit();
++      cpu_clear(cpu, flush_cpumask);
++      smp_mb__after_clear_bit();
+ out:
+       put_cpu_no_resched();
+ }
+-static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
++static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
+                                               unsigned long va)
+ {
++      cpumask_t tmp;
+       /*
+        * A couple of (to be removed) sanity checks:
+        *
+@@ -348,14 +353,12 @@ static void flush_tlb_others (unsigned l
+        * - current CPU must not be in mask
+        * - mask must exist :)
+        */
+-      if (!cpumask)
+-              BUG();
+-      if ((cpumask & cpu_online_map) != cpumask)
+-              BUG();
+-      if (cpumask & (1 << smp_processor_id()))
+-              BUG();
+-      if (!mm)
+-              BUG();
++      BUG_ON(cpus_empty(cpumask));
++
++      cpus_and(tmp, cpumask, cpu_online_map);
++      BUG_ON(!cpus_equal(cpumask, tmp));
++      BUG_ON(cpu_isset(smp_processor_id(), cpumask));
++      BUG_ON(!mm);
+       /*
+        * i'm not happy about this global shared spinlock in the
+@@ -367,15 +370,26 @@ static void flush_tlb_others (unsigned l
+       
+       flush_mm = mm;
+       flush_va = va;
++#if NR_CPUS <= BITS_PER_LONG
+       atomic_set_mask(cpumask, &flush_cpumask);
++#else
++      {
++              int k;
++              unsigned long *flush_mask = (unsigned long *)&flush_cpumask;
++              unsigned long *cpu_mask = (unsigned long *)&cpumask;
++              for (k = 0; k < BITS_TO_LONGS(NR_CPUS); ++k)
++                      atomic_set_mask(cpu_mask[k], &flush_mask[k]);
++      }
++#endif
+       /*
+        * We have to send the IPI only to
+        * CPUs affected.
+        */
+       send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR);
+-      while (flush_cpumask)
+-              /* nothing. lockup detection does not belong here */;
++      while (!cpus_empty(flush_cpumask))
++              /* nothing. lockup detection does not belong here */
++              mb();
+       flush_mm = NULL;
+       flush_va = 0;
+@@ -385,23 +399,25 @@ static void flush_tlb_others (unsigned l
+ void flush_tlb_current_task(void)
+ {
+       struct mm_struct *mm = current->mm;
+-      unsigned long cpu_mask;
++      cpumask_t cpu_mask;
+       preempt_disable();
+-      cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
++      cpu_mask = mm->cpu_vm_mask;
++      cpu_clear(smp_processor_id(), cpu_mask);
+       local_flush_tlb();
+-      if (cpu_mask)
++      if (!cpus_empty(cpu_mask))
+               flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+       preempt_enable();
+ }
+ void flush_tlb_mm (struct mm_struct * mm)
+ {
+-      unsigned long cpu_mask;
++      cpumask_t cpu_mask;
+       preempt_disable();
+-      cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
++      cpu_mask = mm->cpu_vm_mask;
++      cpu_clear(smp_processor_id(), cpu_mask);
+       if (current->active_mm == mm) {
+               if (current->mm)
+@@ -409,7 +425,7 @@ void flush_tlb_mm (struct mm_struct * mm
+               else
+                       leave_mm(smp_processor_id());
+       }
+-      if (cpu_mask)
++      if (!cpus_empty(cpu_mask))
+               flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+       preempt_enable();
+@@ -418,10 +434,11 @@ void flush_tlb_mm (struct mm_struct * mm
+ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
+ {
+       struct mm_struct *mm = vma->vm_mm;
+-      unsigned long cpu_mask;
++      cpumask_t cpu_mask;
+       preempt_disable();
+-      cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
++      cpu_mask = mm->cpu_vm_mask;
++      cpu_clear(smp_processor_id(), cpu_mask);
+       if (current->active_mm == mm) {
+               if(current->mm)
+@@ -430,7 +447,7 @@ void flush_tlb_page(struct vm_area_struc
+                       leave_mm(smp_processor_id());
+       }
+-      if (cpu_mask)
++      if (!cpus_empty(cpu_mask))
+               flush_tlb_others(cpu_mask, mm, va);
+       preempt_enable();
+@@ -457,9 +474,19 @@ void flush_tlb_all(void)
+  */
+ void smp_send_reschedule(int cpu)
+ {
+-      send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR);
++      send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
+ }
+-
++#ifdef CONFIG_KGDB
++/*
++ * By using the NMI code instead of a vector we just sneak thru the 
++ * word generator coming out with just what we want.  AND it does
++ * not matter if clustered_apic_mode is set or not.
++ */
++void smp_send_nmi_allbutself(void)
++{
++      send_IPI_allbutself(APIC_DM_NMI);
++}
++#endif
+ /*
+  * Structure and data for smp_call_function(). This is designed to minimise
+  * static memory requirements. It also looks cleaner.
+@@ -533,7 +560,7 @@ static void stop_this_cpu (void * dummy)
+       /*
+        * Remove this CPU:
+        */
+-      clear_bit(smp_processor_id(), &cpu_online_map);
++      cpu_clear(smp_processor_id(), cpu_online_map);
+       local_irq_disable();
+       disable_local_APIC();
+       if (cpu_data[smp_processor_id()].hlt_works_ok)
+--- linux-2.6.0-test1/arch/i386/kernel/traps.c 2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/i386/kernel/traps.c        2003-07-19 17:06:40.000000000 -0700
+@@ -90,6 +90,42 @@ asmlinkage void alignment_check(void);
+ asmlinkage void spurious_interrupt_bug(void);
+ asmlinkage void machine_check(void);
++#ifdef CONFIG_KGDB
++extern void sysenter_entry(void);
++#include <asm/kgdb.h>
++#include <linux/init.h>
++extern void int3(void);
++extern void debug(void);
++void set_intr_gate(unsigned int n, void *addr);
++static void set_intr_usr_gate(unsigned int n, void *addr);
++/*
++ * Should be able to call this breakpoint() very early in
++ * bring up.  Just hard code the call where needed.
++ * The breakpoint() code is here because set_?_gate() functions
++ * are local (static) to trap.c.  They need be done only once,
++ * but it does not hurt to do them over.
++ */
++void breakpoint(void)
++{
++        set_intr_usr_gate(3,&int3); /* disable ints on trap */
++      set_intr_gate(1,&debug);
++      set_intr_gate(14,&page_fault);
++       
++        BREAKPOINT;
++}
++#define       CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)            \
++    {                                                                 \
++      if (!user_mode(regs)  ) \
++      {                                                               \
++              kgdb_handle_exception(trapnr, signr, error_code, regs); \
++              after;                                                  \
++      } else if ((trapnr == 3) && (regs->eflags &0x200)) local_irq_enable(); \
++    }
++#else
++#define       CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)    
++#endif
++
++
+ static int kstack_depth_to_print = 24;
+ void show_trace(struct task_struct *task, unsigned long * stack)
+@@ -172,8 +208,9 @@ void show_registers(struct pt_regs *regs
+               ss = regs->xss & 0xffff;
+       }
+       print_modules();
+-      printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx\n",
+-              smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
++      printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\nEFLAGS: %08lx\n",
++              smp_processor_id(), 0xffff & regs->xcs,
++              regs->eip, print_tainted(), regs->eflags);
+       print_symbol("EIP is at %s\n", regs->eip);
+       printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
+@@ -189,23 +226,25 @@ void show_registers(struct pt_regs *regs
+        * time of the fault..
+        */
+       if (in_kernel) {
++              u8 *eip;
+               printk("\nStack: ");
+               show_stack(NULL, (unsigned long*)esp);
+               printk("Code: ");
+-              if(regs->eip < PAGE_OFFSET)
+-                      goto bad;
+-              for(i=0;i<20;i++)
+-              {
++              eip = (u8 *)regs->eip - 43;
++              for (i = 0; i < 64; i++, eip++) {
+                       unsigned char c;
+-                      if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
+-bad:
++
++                      if (eip < (u8 *)PAGE_OFFSET || __get_user(c, eip)) {
+                               printk(" Bad EIP value.");
+                               break;
+                       }
+-                      printk("%02x ", c);
++                      if (eip == (u8 *)regs->eip)
++                              printk("<%02x> ", c);
++                      else
++                              printk("%02x ", c);
+               }
+       }
+       printk("\n");
+@@ -252,12 +291,36 @@ spinlock_t die_lock = SPIN_LOCK_UNLOCKED
+ void die(const char * str, struct pt_regs * regs, long err)
+ {
+       static int die_counter;
++      int nl = 0;
+       console_verbose();
+       spin_lock_irq(&die_lock);
+       bust_spinlocks(1);
+       handle_BUG(regs);
+       printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
++#ifdef CONFIG_PREEMPT
++      printk("PREEMPT ");
++      nl = 1;
++#endif
++#ifdef CONFIG_SMP
++      printk("SMP ");
++      nl = 1;
++#endif
++#ifdef CONFIG_DEBUG_PAGEALLOC
++      printk("DEBUG_PAGEALLOC");
++      nl = 1;
++#endif
++      if (nl)
++              printk("\n");
++#ifdef CONFIG_KGDB
++      /* This is about the only place we want to go to kgdb even if in 
++       * user mode.  But we must go in via a trap so within kgdb we will
++       * always be in kernel mode.
++       */
++      if (user_mode(regs))
++              BREAKPOINT;
++#endif
++      CHK_REMOTE_DEBUG(0,SIGTRAP,err,regs,)
+       show_registers(regs);
+       bust_spinlocks(0);
+       spin_unlock_irq(&die_lock);
+@@ -327,6 +390,7 @@ static inline void do_trap(int trapnr, i
+ #define DO_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
++      CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,)\
+       do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
+ }
+@@ -344,7 +408,9 @@ asmlinkage void do_##name(struct pt_regs
+ #define DO_VM86_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
++      CHK_REMOTE_DEBUG(trapnr, signr, error_code,regs, return)\
+       do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
++      return; \
+ }
+ #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
+@@ -387,8 +453,10 @@ gp_in_vm86:
+       return;
+ gp_in_kernel:
+-      if (!fixup_exception(regs))
++      if (!fixup_exception(regs)){
++              CHK_REMOTE_DEBUG(13,SIGSEGV,error_code,regs,)
+               die("general protection fault", regs, error_code);
++      }
+ }
+ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+@@ -550,8 +618,18 @@ asmlinkage void do_debug(struct pt_regs 
+                * allowing programs to debug themselves without the ptrace()
+                * interface.
+                */
+-              if ((regs->xcs & 3) == 0)
++#ifdef CONFIG_KGDB
++              /*
++               * I think this is the only "real" case of a TF in the kernel
++               * that really belongs to user space.  Others are
++               * "Ours all ours!"
++               */
++              if (((regs->xcs & 3) == 0) && ((void *)regs->eip == sysenter_entry))
++                      goto clear_TF_reenable;
++#else
++              if ((regs->xcs & 3) == 0)       
+                       goto clear_TF_reenable;
++#endif
+               if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
+                       goto clear_TF;
+       }
+@@ -563,6 +641,17 @@ asmlinkage void do_debug(struct pt_regs 
+       info.si_errno = 0;
+       info.si_code = TRAP_BRKPT;
+       
++#ifdef CONFIG_KGDB
++        /*
++       * If this is a kernel mode trap, we need to reset db7 to allow us
++       * to continue sanely ALSO skip the signal delivery 
++         */
++      if ((regs->xcs & 3) == 0)
++              goto clear_dr7;
++
++        /* if not kernel, allow ints but only if they were on */ 
++       if ( regs->eflags & 0x200) local_irq_enable(); 
++#endif
+       /* If this is a kernel mode trap, save the user PC on entry to 
+        * the kernel, that's what the debugger can make sense of.
+        */
+@@ -577,6 +666,7 @@ clear_dr7:
+       __asm__("movl %0,%%db7"
+               : /* no output */
+               : "r" (0));
++      CHK_REMOTE_DEBUG(1,SIGTRAP,error_code,regs,)
+       return;
+ debug_vm86:
+@@ -823,6 +913,12 @@ static void __init set_call_gate(void *a
+ {
+       _set_gate(a,12,3,addr,__KERNEL_CS);
+ }
++#ifdef CONFIG_KGDB
++void set_intr_usr_gate(unsigned int n, void *addr)
++{
++      _set_gate(idt_table+n,14,3,addr,__KERNEL_CS);
++}
++#endif
+ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
+ {
+@@ -849,7 +945,11 @@ void __init trap_init(void)
+       set_trap_gate(0,&divide_error);
+       set_intr_gate(1,&debug);
+       set_intr_gate(2,&nmi);
++#ifndef CONFIG_KGDB
+       set_system_gate(3,&int3);       /* int3-5 can be called from all */
++#else
++      set_intr_usr_gate(3,&int3);     /* int3-5 can be called from all */
++#endif
+       set_system_gate(4,&overflow);
+       set_system_gate(5,&bounds);
+       set_trap_gate(6,&invalid_op);
+--- linux-2.6.0-test1/arch/i386/kernel/vm86.c  2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/i386/kernel/vm86.c 2003-07-19 17:07:16.000000000 -0700
+@@ -144,12 +144,14 @@ static void mark_screen_rdonly(struct ta
+               pgd_clear(pgd);
+               goto out;
+       }
+-      pmd = pmd_offset(pgd, 0xA0000);
+-      if (pmd_none(*pmd))
++      pmd = pmd_offset_map(pgd, 0xA0000);
++      if (pmd_none(*pmd)) {
++              pmd_unmap(pmd);
+               goto out;
+-      if (pmd_bad(*pmd)) {
++      } else if (pmd_bad(*pmd)) {
+               pmd_ERROR(*pmd);
+               pmd_clear(pmd);
++              pmd_unmap(pmd);
+               goto out;
+       }
+       pte = mapped = pte_offset_map(pmd, 0xA0000);
+@@ -159,6 +161,7 @@ static void mark_screen_rdonly(struct ta
+               pte++;
+       }
+       pte_unmap(mapped);
++      pmd_unmap(pmd);
+ out:
+       spin_unlock(&tsk->mm->page_table_lock);
+       preempt_enable();
+--- linux-2.6.0-test1/arch/i386/lib/dec_and_lock.c     2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/lib/dec_and_lock.c    2003-07-19 17:06:40.000000000 -0700
+@@ -10,6 +10,7 @@
+ #include <linux/spinlock.h>
+ #include <asm/atomic.h>
++#ifndef ATOMIC_DEC_AND_LOCK
+ int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
+ {
+       int counter;
+@@ -38,3 +39,5 @@ slow_path:
+       spin_unlock(lock);
+       return 0;
+ }
++#endif
++
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/lib/kgdb_serial.c     2003-07-19 17:04:02.000000000 -0700
+@@ -0,0 +1,485 @@
++/*
++ * Serial interface GDB stub
++ *
++ * Written (hacked together) by David Grothe (dave@gcom.com)
++ * Modified to allow invokation early in boot see also
++ * kgdb.h for instructions by George Anzinger(george@mvista.com)
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial.h>
++#include <linux/serial_reg.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/highmem.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/segment.h>
++#include <asm/bitops.h>
++#include <asm/system.h>
++#include <asm/kgdb_local.h>
++#ifdef CONFIG_KGDB_USER_CONSOLE
++extern void kgdb_console_finit(void);
++#endif
++#define PRNT_off
++#define TEST_EXISTANCE
++#ifdef PRNT
++#define dbprintk(s) printk s
++#else
++#define dbprintk(s)
++#endif
++#define TEST_INTERRUPT_off
++#ifdef TEST_INTERRUPT
++#define intprintk(s) printk s
++#else
++#define intprintk(s)
++#endif
++
++#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
++
++#define       GDB_BUF_SIZE    512     /* power of 2, please */
++
++static char gdb_buf[GDB_BUF_SIZE];
++static int gdb_buf_in_inx;
++static atomic_t gdb_buf_in_cnt;
++static int gdb_buf_out_inx;
++
++struct async_struct *gdb_async_info;
++static int gdb_async_irq;
++
++#define outb_px(a,b) outb_p(b,a)
++
++static void program_uart(struct async_struct *info);
++static void write_char(struct async_struct *info, int chr);
++/*
++ * Get a byte from the hardware data buffer and return it
++ */
++static int
++read_data_bfr(struct async_struct *info)
++{
++      char it = inb_p(info->port + UART_LSR);
++
++      if (it & UART_LSR_DR)
++              return (inb_p(info->port + UART_RX));
++      /*
++       * If we have a framing error assume somebody messed with
++       * our uart.  Reprogram it and send '-' both ways...
++       */
++      if (it & 0xc) {
++              program_uart(info);
++              write_char(info, '-');
++              return ('-');
++      }
++      return (-1);
++
++}                             /* read_data_bfr */
++
++/*
++ * Get a char if available, return -1 if nothing available.
++ * Empty the receive buffer first, then look at the interface hardware.
++
++ * Locking here is a bit of a problem.        We MUST not lock out communication
++ * if we are trying to talk to gdb about a kgdb entry.        ON the other hand
++ * we can loose chars in the console pass thru if we don't lock.  It is also
++ * possible that we could hold the lock or be waiting for it when kgdb
++ * NEEDS to talk.  Since kgdb locks down the world, it does not need locks.
++ * We do, of course have possible issues with interrupting a uart operation,
++ * but we will just depend on the uart status to help keep that straight.
++
++ */
++static spinlock_t uart_interrupt_lock = SPIN_LOCK_UNLOCKED;
++#ifdef CONFIG_SMP
++extern spinlock_t kgdb_spinlock;
++#endif
++
++static int
++read_char(struct async_struct *info)
++{
++      int chr;
++      unsigned long flags;
++      local_irq_save(flags);
++#ifdef CONFIG_SMP
++      if (!spin_is_locked(&kgdb_spinlock)) {
++              spin_lock(&uart_interrupt_lock);
++      }
++#endif
++      if (atomic_read(&gdb_buf_in_cnt) != 0) {        /* intr routine has q'd chars */
++              chr = gdb_buf[gdb_buf_out_inx++];
++              gdb_buf_out_inx &= (GDB_BUF_SIZE - 1);
++              atomic_dec(&gdb_buf_in_cnt);
++      } else {
++              chr = read_data_bfr(info);
++      }
++#ifdef CONFIG_SMP
++      if (!spin_is_locked(&kgdb_spinlock)) {
++              spin_unlock(&uart_interrupt_lock);
++      }
++#endif
++      local_irq_restore(flags);
++      return (chr);
++}
++
++/*
++ * Wait until the interface can accept a char, then write it.
++ */
++static void
++write_char(struct async_struct *info, int chr)
++{
++      while (!(inb_p(info->port + UART_LSR) & UART_LSR_THRE)) ;
++
++      outb_p(chr, info->port + UART_TX);
++
++}                             /* write_char */
++
++/*
++ * Mostly we don't need a spinlock, but since the console goes
++ * thru here with interrutps on, well, we need to catch those
++ * chars.
++ */
++/*
++ * This is the receiver interrupt routine for the GDB stub.
++ * It will receive a limited number of characters of input
++ * from the gdb  host machine and save them up in a buffer.
++ *
++ * When the gdb stub routine getDebugChar() is called it
++ * draws characters out of the buffer until it is empty and
++ * then reads directly from the serial port.
++ *
++ * We do not attempt to write chars from the interrupt routine
++ * since the stubs do all of that via putDebugChar() which
++ * writes one byte after waiting for the interface to become
++ * ready.
++ *
++ * The debug stubs like to run with interrupts disabled since,
++ * after all, they run as a consequence of a breakpoint in
++ * the kernel.
++ *
++ * Perhaps someone who knows more about the tty driver than I
++ * care to learn can make this work for any low level serial
++ * driver.
++ */
++static irqreturn_t
++gdb_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct async_struct *info;
++      unsigned long flags;
++
++      info = gdb_async_info;
++      if (!info || !info->tty || irq != gdb_async_irq)
++              return IRQ_NONE;
++
++      local_irq_save(flags);
++      spin_lock(&uart_interrupt_lock);
++      do {
++              int chr = read_data_bfr(info);
++              intprintk(("Debug char on int: %x hex\n", chr));
++              if (chr < 0)
++                      continue;
++
++              if (chr == 3) { /* Ctrl-C means remote interrupt */
++                      BREAKPOINT;
++                      continue;
++              }
++
++              if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE) {
++                      /* buffer overflow tosses early char */
++                      read_char(info);
++              }
++              gdb_buf[gdb_buf_in_inx++] = chr;
++              gdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
++      } while (inb_p(info->port + UART_IIR) & UART_IIR_RDI);
++      spin_unlock(&uart_interrupt_lock);
++      local_irq_restore(flags);
++      return IRQ_HANDLED;
++}                             /* gdb_interrupt */
++
++/*
++ * Just a NULL routine for testing.
++ */
++void
++gdb_null(void)
++{
++}                             /* gdb_null */
++
++/* These structure are filled in with values defined in asm/kgdb_local.h
++ */
++static struct serial_state state = SB_STATE;
++static struct async_struct local_info = SB_INFO;
++static int ok_to_enable_ints = 0;
++static void kgdb_enable_ints_now(void);
++
++extern char *kgdb_version;
++/*
++ * Hook an IRQ for KGDB.
++ *
++ * This routine is called from putDebugChar, below.
++ */
++static int ints_disabled = 1;
++int
++gdb_hook_interrupt(struct async_struct *info, int verb)
++{
++      struct serial_state *state = info->state;
++      unsigned long flags;
++      int port;
++#ifdef TEST_EXISTANCE
++      int scratch, scratch2;
++#endif
++
++      /* The above fails if memory managment is not set up yet. 
++       * Rather than fail the set up, just keep track of the fact
++       * and pick up the interrupt thing later.
++       */
++      gdb_async_info = info;
++      port = gdb_async_info->port;
++      gdb_async_irq = state->irq;
++      if (verb) {
++              printk("kgdb %s : port =%x, IRQ=%d, divisor =%d\n",
++                     kgdb_version,
++                     port,
++                     gdb_async_irq, gdb_async_info->state->custom_divisor);
++      }
++      local_irq_save(flags);
++#ifdef TEST_EXISTANCE
++      /* Existance test */
++      /* Should not need all this, but just in case.... */
++
++      scratch = inb_p(port + UART_IER);
++      outb_px(port + UART_IER, 0);
++      outb_px(0xff, 0x080);
++      scratch2 = inb_p(port + UART_IER);
++      outb_px(port + UART_IER, scratch);
++      if (scratch2) {
++              printk
++                  ("gdb_hook_interrupt: Could not clear IER, not a UART!\n");
++              local_irq_restore(flags);
++              return 1;       /* We failed; there's nothing here */
++      }
++      scratch2 = inb_p(port + UART_LCR);
++      outb_px(port + UART_LCR, 0xBF); /* set up for StarTech test */
++      outb_px(port + UART_EFR, 0);    /* EFR is the same as FCR */
++      outb_px(port + UART_LCR, 0);
++      outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO);
++      scratch = inb_p(port + UART_IIR) >> 6;
++      if (scratch == 1) {
++              printk("gdb_hook_interrupt: Undefined UART type!"
++                     "  Not a UART! \n");
++              local_irq_restore(flags);
++              return 1;
++      } else {
++              dbprintk(("gdb_hook_interrupt: UART type "
++                        "is %d where 0=16450, 2=16550 3=16550A\n", scratch));
++      }
++      scratch = inb_p(port + UART_MCR);
++      outb_px(port + UART_MCR, UART_MCR_LOOP | scratch);
++      outb_px(port + UART_MCR, UART_MCR_LOOP | 0x0A);
++      scratch2 = inb_p(port + UART_MSR) & 0xF0;
++      outb_px(port + UART_MCR, scratch);
++      if (scratch2 != 0x90) {
++              printk("gdb_hook_interrupt: "
++                     "Loop back test failed! Not a UART!\n");
++              local_irq_restore(flags);
++              return scratch2 + 1000; /* force 0 to fail */
++      }
++#endif                                /* test existance */
++      program_uart(info);
++      local_irq_restore(flags);
++
++      return (0);
++
++}                             /* gdb_hook_interrupt */
++
++static void
++program_uart(struct async_struct *info)
++{
++      int port = info->port;
++
++      (void) inb_p(port + UART_RX);
++      outb_px(port + UART_IER, 0);
++
++      (void) inb_p(port + UART_RX);   /* serial driver comments say */
++      (void) inb_p(port + UART_IIR);  /* this clears the interrupt regs */
++      (void) inb_p(port + UART_MSR);
++      outb_px(port + UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
++      outb_px(port + UART_DLL, info->state->custom_divisor & 0xff);   /* LS */
++      outb_px(port + UART_DLM, info->state->custom_divisor >> 8);     /* MS  */
++      outb_px(port + UART_MCR, info->MCR);
++
++      outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1 | UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR);        /* set fcr */
++      outb_px(port + UART_LCR, UART_LCR_WLEN8);       /* reset DLAB */
++      outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1);    /* set fcr */
++      if (!ints_disabled) {
++              intprintk(("KGDB: Sending %d to port %x offset %d\n",
++                         gdb_async_info->IER,
++                         (int) gdb_async_info->port, UART_IER));
++              outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
++      }
++      return;
++}
++
++/*
++ * getDebugChar
++ *
++ * This is a GDB stub routine.        It waits for a character from the
++ * serial interface and then returns it.  If there is no serial
++ * interface connection then it returns a bogus value which will
++ * almost certainly cause the system to hang.  In the 
++ */
++int kgdb_in_isr = 0;
++int kgdb_in_lsr = 0;
++extern spinlock_t kgdb_spinlock;
++
++/* Caller takes needed protections */
++
++int
++getDebugChar(void)
++{
++      volatile int chr, dum, time, end_time;
++
++      dbprintk(("getDebugChar(port %x): ", gdb_async_info->port));
++
++      if (gdb_async_info == NULL) {
++              gdb_hook_interrupt(&local_info, 0);
++      }
++      /* 
++       * This trick says if we wait a very long time and get
++       * no char, return the -1 and let the upper level deal
++       * with it.
++       */
++      rdtsc(dum, time);
++      end_time = time + 2;
++      while (((chr = read_char(gdb_async_info)) == -1) &&
++             (end_time - time) > 0) {
++              rdtsc(dum, time);
++      };
++      /*
++       * This covers our butts if some other code messes with
++       * our uart, hay, it happens :o)
++       */
++      if (chr == -1)
++              program_uart(gdb_async_info);
++
++      dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
++      return (chr);
++
++}                             /* getDebugChar */
++
++static int count = 3;
++static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
++
++static int __init
++kgdb_enable_ints(void)
++{
++      if (gdb_async_info == NULL) {
++              gdb_hook_interrupt(&local_info, 1);
++      }
++      ok_to_enable_ints = 1;
++      kgdb_enable_ints_now();
++#ifdef CONFIG_KGDB_USER_CONSOLE
++      kgdb_console_finit();
++#endif
++      return 0;
++}
++
++#ifdef CONFIG_SERIAL_8250
++void shutdown_for_kgdb(struct async_struct *gdb_async_info);
++#endif
++
++#ifdef CONFIG_DISCONTIGMEM
++static inline int kgdb_mem_init_done(void)
++{
++      return highmem_start_page != NULL;
++}
++#else
++static inline int kgdb_mem_init_done(void)
++{
++      return max_mapnr != 0;
++}
++#endif
++
++static void
++kgdb_enable_ints_now(void)
++{
++      if (!spin_trylock(&one_at_atime))
++              return;
++      if (!ints_disabled)
++              goto exit;
++      if (kgdb_mem_init_done() &&
++                      ints_disabled) {        /* don't try till mem init */
++#ifdef CONFIG_SERIAL_8250
++              /*
++               * The ifdef here allows the system to be configured
++               * without the serial driver.
++               * Don't make it a module, however, it will steal the port
++               */
++              shutdown_for_kgdb(gdb_async_info);
++#endif
++              ints_disabled = request_irq(gdb_async_info->state->irq,
++                                          gdb_interrupt,
++                                          IRQ_T(gdb_async_info),
++                                          "KGDB-stub", NULL);
++              intprintk(("KGDB: request_irq returned %d\n", ints_disabled));
++      }
++      if (!ints_disabled) {
++              intprintk(("KGDB: Sending %d to port %x offset %d\n",
++                         gdb_async_info->IER,
++                         (int) gdb_async_info->port, UART_IER));
++              outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
++      }
++      exit:
++      spin_unlock(&one_at_atime);
++}
++
++/*
++ * putDebugChar
++ *
++ * This is a GDB stub routine.        It waits until the interface is ready
++ * to transmit a char and then sends it.  If there is no serial
++ * interface connection then it simply returns to its caller, having
++ * pretended to send the char.        Caller takes needed protections.
++ */
++void
++putDebugChar(int chr)
++{
++      dbprintk(("putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
++                gdb_async_info->port,
++                chr,
++                chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
++
++      if (gdb_async_info == NULL) {
++              gdb_hook_interrupt(&local_info, 0);
++      }
++
++      write_char(gdb_async_info, chr);        /* this routine will wait */
++      count = (chr == '#') ? 0 : count + 1;
++      if ((count == 2)) {     /* try to enable after */
++              if (ints_disabled & ok_to_enable_ints)
++                      kgdb_enable_ints_now(); /* try to enable after */
++
++              /* We do this a lot because, well we really want to get these
++               * interrupts.  The serial driver will clear these bits when it
++               * initializes the chip.  Every thing else it does is ok, 
++               * but this.
++               */
++              if (!ints_disabled) {
++                      outb_px(gdb_async_info->port + UART_IER,
++                              gdb_async_info->IER);
++              }
++      }
++
++}                             /* putDebugChar */
++
++module_init(kgdb_enable_ints);
+--- linux-2.6.0-test1/arch/i386/lib/Makefile   2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/lib/Makefile  2003-07-19 17:04:02.000000000 -0700
+@@ -9,4 +9,5 @@ lib-y = checksum.o delay.o \
+ lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
+ lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
++lib-$(CONFIG_KGDB) += kgdb_serial.o
+ lib-$(CONFIG_DEBUG_IOVIRT)  += iodebug.o
+--- linux-2.6.0-test1/arch/i386/mach-generic/bigsmp.c  2003-06-14 12:18:05.000000000 -0700
++++ 25/arch/i386/mach-generic/bigsmp.c 2003-07-19 17:04:13.000000000 -0700
+@@ -3,6 +3,10 @@
+  * Drives the local APIC in "clustered mode".
+  */
+ #define APIC_DEFINITION 1
++#include <linux/config.h>
++#include <linux/threads.h>
++#include <linux/cpumask.h>
++#include <asm/mpspec.h>
+ #include <asm/genapic.h>
+ #include <asm/fixmap.h>
+ #include <asm/apicdef.h>
+--- linux-2.6.0-test1/arch/i386/mach-generic/default.c 2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/i386/mach-generic/default.c        2003-07-19 17:04:13.000000000 -0700
+@@ -2,6 +2,10 @@
+  * Default generic APIC driver. This handles upto 8 CPUs.
+  */
+ #define APIC_DEFINITION 1
++#include <linux/config.h>
++#include <linux/threads.h>
++#include <linux/cpumask.h>
++#include <asm/mpspec.h>
+ #include <asm/mach-default/mach_apicdef.h>
+ #include <asm/genapic.h>
+ #include <asm/fixmap.h>
+--- linux-2.6.0-test1/arch/i386/mach-generic/probe.c   2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/i386/mach-generic/probe.c  2003-07-19 17:04:13.000000000 -0700
+@@ -3,11 +3,15 @@
+  * 
+  * Generic x86 APIC driver probe layer.
+  */  
++#include <linux/config.h>
++#include <linux/threads.h>
++#include <linux/cpumask.h>
+ #include <linux/string.h>
+ #include <linux/kernel.h>
+ #include <linux/ctype.h>
+ #include <linux/init.h>
+ #include <asm/fixmap.h>
++#include <asm/mpspec.h>
+ #include <asm/apicdef.h>
+ #include <asm/genapic.h>
+--- linux-2.6.0-test1/arch/i386/mach-generic/summit.c  2003-06-14 12:18:34.000000000 -0700
++++ 25/arch/i386/mach-generic/summit.c 2003-07-19 17:04:13.000000000 -0700
+@@ -2,6 +2,10 @@
+  * APIC driver for the IBM "Summit" chipset.
+  */
+ #define APIC_DEFINITION 1
++#include <linux/config.h>
++#include <linux/threads.h>
++#include <linux/cpumask.h>
++#include <asm/mpspec.h>
+ #include <asm/genapic.h>
+ #include <asm/fixmap.h>
+ #include <asm/apicdef.h>
+--- linux-2.6.0-test1/arch/i386/mach-visws/mpparse.c   2003-06-14 12:18:04.000000000 -0700
++++ 25/arch/i386/mach-visws/mpparse.c  2003-07-19 17:04:06.000000000 -0700
+@@ -26,7 +26,7 @@ unsigned int boot_cpu_physical_apicid = 
+ unsigned int boot_cpu_logical_apicid = -1U;
+ /* Bitmask of physically existing CPUs */
+-unsigned long phys_cpu_present_map;
++cpumask_t phys_cpu_present_map;
+ /*
+@@ -38,6 +38,7 @@ unsigned long phys_cpu_present_map;
+ void __init MP_processor_info (struct mpc_config_processor *m)
+ {
+       int ver, logical_apicid;
++      cpumask_t apic_cpus;
+       
+       if (!(m->mpc_cpuflag & CPU_ENABLED))
+               return;
+@@ -62,7 +63,8 @@ void __init MP_processor_info (struct mp
+       }
+       ver = m->mpc_apicver;
+-      phys_cpu_present_map |= apicid_to_cpu_present(m->mpc_apicid);
++      apic_cpus = apicid_to_cpu_present(m->mpc_apicid);
++      cpus_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
+       /*
+        * Validate version
+        */
+--- linux-2.6.0-test1/arch/i386/mach-voyager/voyager_smp.c     2003-06-14 12:18:07.000000000 -0700
++++ 25/arch/i386/mach-voyager/voyager_smp.c    2003-07-19 17:04:06.000000000 -0700
+@@ -75,15 +75,15 @@ static int voyager_extended_cpus = 1;
+ int smp_found_config = 0;
+ /* Used for the invalidate map that's also checked in the spinlock */
+-volatile unsigned long smp_invalidate_needed;
++static volatile unsigned long smp_invalidate_needed;
+ /* Bitmask of currently online CPUs - used by setup.c for
+    /proc/cpuinfo, visible externally but still physical */
+-unsigned long cpu_online_map = 0;
++cpumask_t cpu_online_map = CPU_MASK_NONE;
+ /* Bitmask of CPUs present in the system - exported by i386_syms.c, used
+  * by scheduler but indexed physically */
+-unsigned long phys_cpu_present_map = 0;
++cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
+ /* estimate of time used to flush the SMP-local cache - used in
+  * processor affinity calculations */
+@@ -108,7 +108,7 @@ static void enable_local_vic_irq(unsigne
+ static void disable_local_vic_irq(unsigned int irq);
+ static void before_handle_vic_irq(unsigned int irq);
+ static void after_handle_vic_irq(unsigned int irq);
+-static void set_vic_irq_affinity(unsigned int irq, unsigned long mask);
++static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask);
+ static void ack_vic_irq(unsigned int irq);
+ static void vic_enable_cpi(void);
+ static void do_boot_cpu(__u8 cpuid);
+@@ -128,13 +128,12 @@ send_one_QIC_CPI(__u8 cpu, __u8 cpi)
+ static inline void
+ send_QIC_CPI(__u32 cpuset, __u8 cpi)
+ {
+-      int mask;
+-      __u8 cpu;
++      int cpu;
+-      for_each_cpu(cpu, mask) {
++      for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) {
+               if(cpuset & (1<<cpu)) {
+ #ifdef VOYAGER_DEBUG
+-                      if(!test_bit(cpu, cpu_online_map))
++                      if(!cpu_isset(cpu, cpu_online_map))
+                               VDEBUG(("CPU%d sending cpi %d to CPU%d not in cpu_online_map\n", hard_smp_processor_id(), cpi, cpu));
+ #endif
+                       send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
+@@ -155,7 +154,7 @@ static inline void
+ send_CPI_allbutself(__u8 cpi)
+ {
+       __u8 cpu = smp_processor_id();
+-      __u32 mask = (cpu_online_map & (~(1<<cpu)));
++      __u32 mask = cpus_coerce(cpu_online_map) & ~(1 << cpu);
+       send_CPI(mask, cpi);
+ }
+@@ -243,11 +242,11 @@ static __u32 cpu_booted_map;
+ /* the synchronize flag used to hold all secondary CPUs spinning in
+  * a tight loop until the boot sequence is ready for them */
+-static unsigned long smp_commenced_mask = 0;
++static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
+ /* This is for the new dynamic CPU boot code */
+-volatile unsigned long cpu_callin_map = 0;
+-volatile unsigned long cpu_callout_map = 0;
++volatile cpumask_t cpu_callin_map = CPU_MASK_NONE;
++volatile cpumask_t cpu_callout_map = CPU_MASK_NONE;
+ /* The per processor IRQ masks (these are usually kept in sync) */
+ static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
+@@ -395,7 +394,7 @@ find_smp_config(void)
+       for(i=0; i<NR_CPUS; i++) {
+               cpu_irq_affinity[i] = ~0;
+       }
+-      cpu_online_map = (1<<boot_cpu_id);
++      cpu_online_map = cpumask_of_cpu(boot_cpu_id);
+       /* The boot CPU must be extended */
+       voyager_extended_vic_processors = 1<<boot_cpu_id;
+@@ -404,11 +403,11 @@ find_smp_config(void)
+       /* set up everything for just this CPU, we can alter
+        * this as we start the other CPUs later */
+       /* now get the CPU disposition from the extended CMOS */
+-      phys_cpu_present_map = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
+-      phys_cpu_present_map |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
+-      phys_cpu_present_map |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16;
+-      phys_cpu_present_map |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24;
+-      printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", phys_cpu_present_map);
++      phys_cpu_present_map = cpus_promote(voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK));
++      cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
++      cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16;
++      cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24;
++      printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_coerce(phys_cpu_present_map));
+       /* Here we set up the VIC to enable SMP */
+       /* enable the CPIs by writing the base vector to their register */
+       outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER);
+@@ -509,18 +508,18 @@ start_secondary(void *unused)
+        * permission to proceed.  Without this, the new per CPU stuff
+        * in the softirqs will fail */
+       local_irq_disable();
+-      set_bit(cpuid, &cpu_callin_map);
++      cpu_set(cpuid, cpu_callin_map);
+       /* signal that we're done */
+       cpu_booted_map = 1;
+-      while (!test_bit(cpuid, &smp_commenced_mask))
++      while (!cpu_isset(cpuid, smp_commenced_mask))
+               rep_nop();
+       local_irq_enable();
+       local_flush_tlb();
+-      set_bit(cpuid, &cpu_online_map);
++      cpu_set(cpuid, cpu_online_map);
+       wmb();
+       return cpu_idle();
+ }
+@@ -674,14 +673,14 @@ do_boot_cpu(__u8 cpu)
+       free_page((unsigned long)page_table_copies);
+ #endif
+         
+-      if(cpu_booted_map) {
++      if (cpu_booted_map) {
+               VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n",
+                       cpu, smp_processor_id()));
+       
+               printk("CPU%d: ", cpu);
+               print_cpu_info(&cpu_data[cpu]);
+               wmb();
+-              set_bit(cpu, &cpu_callout_map);
++              cpu_set(cpu, cpu_callout_map);
+       }
+       else {
+               printk("CPU%d FAILED TO BOOT: ", cpu);
+@@ -708,13 +707,12 @@ smp_boot_cpus(void)
+               /* now that the cat has probed the Voyager System Bus, sanity
+                * check the cpu map */
+               if( ((voyager_quad_processors | voyager_extended_vic_processors)
+-                   & phys_cpu_present_map) != phys_cpu_present_map) {
++                   & cpus_coerce(phys_cpu_present_map)) != cpus_coerce(phys_cpu_present_map)) {
+                       /* should panic */
+                       printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n");
+               }
+-      } else if(voyager_level == 4) {
+-              voyager_extended_vic_processors = phys_cpu_present_map;
+-      }
++      } else if(voyager_level == 4)
++              voyager_extended_vic_processors = cpus_coerce(phys_cpu_present_map);
+       /* this sets up the idle task to run on the current cpu */
+       voyager_extended_cpus = 1;
+@@ -740,13 +738,13 @@ smp_boot_cpus(void)
+       /* enable our own CPIs */
+       vic_enable_cpi();
+-      set_bit(boot_cpu_id, &cpu_online_map);
+-      set_bit(boot_cpu_id, &cpu_callout_map);
++      cpu_set(boot_cpu_id, cpu_online_map);
++      cpu_set(boot_cpu_id, cpu_callout_map);
+       
+       /* loop over all the extended VIC CPUs and boot them.  The 
+        * Quad CPUs must be bootstrapped by their extended VIC cpu */
+       for(i = 0; i < NR_CPUS; i++) {
+-              if( i == boot_cpu_id || ((1<<i) & (phys_cpu_present_map) ) == 0)
++              if(i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map))
+                       continue;
+               do_boot_cpu(i);
+               /* This udelay seems to be needed for the Quad boots
+@@ -758,7 +756,7 @@ smp_boot_cpus(void)
+       {
+               unsigned long bogosum = 0;
+               for (i = 0; i < NR_CPUS; i++)
+-                      if (cpu_online_map & (1<<i))
++                      if (cpu_isset(i, cpu_online_map))
+                               bogosum += cpu_data[i].loops_per_jiffy;
+               printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
+                       cpucount+1,
+@@ -865,7 +863,7 @@ leave_mm (unsigned long cpu)
+ {
+       if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
+               BUG();
+-      clear_bit(cpu,  &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
++      cpu_clear(cpu,  cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
+       load_cr3(swapper_pg_dir);
+ }
+@@ -878,7 +876,7 @@ smp_invalidate_interrupt(void)
+ {
+       __u8 cpu = get_cpu();
+-      if(!test_bit(cpu, &smp_invalidate_needed))
++      if (!(smp_invalidate_needed & (1UL << cpu)))
+               goto out;
+       /* This will flood messages.  Don't uncomment unless you see
+        * Problems with cross cpu invalidation
+@@ -895,7 +893,7 @@ smp_invalidate_interrupt(void)
+               } else
+                       leave_mm(cpu);
+       }
+-      clear_bit(cpu, &smp_invalidate_needed);
++      smp_invalidate_needed |= 1UL << cpu;
+  out:
+       put_cpu_no_resched();
+ }
+@@ -912,7 +910,7 @@ flush_tlb_others (unsigned long cpumask,
+       if (!cpumask)
+               BUG();
+-      if ((cpumask & cpu_online_map) != cpumask)
++      if ((cpumask & cpus_coerce(cpu_online_map)) != cpumask)
+               BUG();
+       if (cpumask & (1 << smp_processor_id()))
+               BUG();
+@@ -954,7 +952,7 @@ flush_tlb_current_task(void)
+       preempt_disable();
+-      cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
++      cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id());
+       local_flush_tlb();
+       if (cpu_mask)
+               flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+@@ -970,7 +968,7 @@ flush_tlb_mm (struct mm_struct * mm)
+       preempt_disable();
+-      cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
++      cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id());
+       if (current->active_mm == mm) {
+               if (current->mm)
+@@ -991,7 +989,7 @@ void flush_tlb_page(struct vm_area_struc
+       preempt_disable();
+-      cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
++      cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id());
+       if (current->active_mm == mm) {
+               if(current->mm)
+                       __flush_tlb_one(va);
+@@ -1033,7 +1031,7 @@ static void
+ smp_stop_cpu_function(void *dummy)
+ {
+       VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id()));
+-      clear_bit(smp_processor_id(), &cpu_online_map);
++      cpu_clear(smp_processor_id(), cpu_online_map);
+       local_irq_disable();
+       for(;;)
+              __asm__("hlt");
+@@ -1100,7 +1098,7 @@ smp_call_function (void (*func) (void *i
+                  int wait)
+ {
+       struct call_data_struct data;
+-      __u32 mask = cpu_online_map;
++      __u32 mask = cpus_coerce(cpu_online_map);
+       mask &= ~(1<<smp_processor_id());
+@@ -1451,8 +1449,7 @@ smp_intr_init(void)
+ static void
+ send_CPI(__u32 cpuset, __u8 cpi)
+ {
+-      int mask;
+-      __u8 cpu;
++      int cpu;
+       __u32 quad_cpuset = (cpuset & voyager_quad_processors);
+       if(cpi < VIC_START_FAKE_CPI) {
+@@ -1467,7 +1464,7 @@ send_CPI(__u32 cpuset, __u8 cpi)
+       cpuset &= 0xff;         /* only first 8 CPUs vaild for VIC CPI */
+       if(cpuset == 0)
+               return;
+-      for_each_cpu(cpu, mask) {
++      for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) {
+               if(cpuset & (1<<cpu))
+                       set_bit(cpi, &vic_cpi_mailbox[cpu]);
+       }
+@@ -1571,10 +1568,9 @@ startup_vic_irq(unsigned int irq)
+ static void
+ enable_vic_irq(unsigned int irq)
+ {
+-      int tmpmask;
+       /* linux doesn't to processor-irq affinity, so enable on
+        * all CPUs we know about */
+-      __u8 cpu = smp_processor_id(), real_cpu;
++      int cpu = smp_processor_id(), real_cpu;
+       __u16 mask = (1<<irq);
+       __u32 processorList = 0;
+       unsigned long flags;
+@@ -1582,7 +1578,7 @@ enable_vic_irq(unsigned int irq)
+       VDEBUG(("VOYAGER: enable_vic_irq(%d) CPU%d affinity 0x%lx\n",
+               irq, cpu, cpu_irq_affinity[cpu]));
+       spin_lock_irqsave(&vic_irq_lock, flags);
+-      for_each_cpu(real_cpu, tmpmask) {
++      for_each_cpu(real_cpu, mk_cpumask_const(cpu_online_map)) {
+               if(!(voyager_extended_vic_processors & (1<<real_cpu)))
+                       continue;
+               if(!(cpu_irq_affinity[real_cpu] & mask)) {
+@@ -1727,7 +1723,7 @@ after_handle_vic_irq(unsigned int irq)
+                       printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
+                              cpu, irq);
+-                      for_each_cpu(real_cpu, mask) {
++                      for_each_cpu(real_cpu, mk_cpumask_const(mask)) {
+                               outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
+                                    VIC_PROCESSOR_ID);
+@@ -1783,15 +1779,16 @@ after_handle_vic_irq(unsigned int irq)
+  * the selected processors */
+ void
+-set_vic_irq_affinity(unsigned int irq, unsigned long mask) 
++set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
+ {
+       /* Only extended processors handle interrupts */
+-      unsigned long real_mask = mask & voyager_extended_vic_processors;
+-      unsigned long irq_mask = (1<<irq);
+-      int tmpmask;
+-      __u8 cpu;
++      unsigned long real_mask;
++      unsigned long irq_mask = 1 << irq;
++      int cpu;
++
++      real_mask = cpus_coerce(mask) & voyager_extended_vic_processors;
+       
+-      if(mask == 0)
++      if(cpus_coerce(mask) == 0)
+               /* can't have no cpu's to accept the interrupt -- extremely
+                * bad things will happen */
+               return;
+@@ -1811,8 +1808,8 @@ set_vic_irq_affinity(unsigned int irq, u
+                * bus) */
+               return;
+-      for_each_cpu(cpu, tmpmask) {
+-              unsigned long cpu_mask = (1<<cpu);
++      for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) {
++              unsigned long cpu_mask = 1 << cpu;
+               
+               if(cpu_mask & real_mask) {
+                       /* enable the interrupt for this cpu */
+@@ -1874,11 +1871,10 @@ vic_enable_cpi(void)
+ void
+ voyager_smp_dump()
+ {
+-      int mask;
+-      __u8 old_cpu = smp_processor_id(), cpu;
++      int old_cpu = smp_processor_id(), cpu;
+       /* dump the interrupt masks of each processor */
+-      for_each_cpu(cpu, mask) {
++      for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) {
+               __u16 imr, isr, irr;
+               unsigned long flags;
+@@ -1936,23 +1932,23 @@ smp_prepare_cpus(unsigned int max_cpus)
+ void __devinit smp_prepare_boot_cpu(void)
+ {
+-      set_bit(smp_processor_id(), &cpu_online_map);
+-      set_bit(smp_processor_id(), &cpu_callout_map);
++      cpu_set(smp_processor_id(), cpu_online_map);
++      cpu_set(smp_processor_id(), cpu_callout_map);
+ }
+ int __devinit
+ __cpu_up(unsigned int cpu)
+ {
+       /* This only works at boot for x86.  See "rewrite" above. */
+-      if (test_bit(cpu, &smp_commenced_mask))
++      if (cpu_isset(cpu, smp_commenced_mask))
+               return -ENOSYS;
+       /* In case one didn't come up */
+-      if (!test_bit(cpu, &cpu_callin_map))
++      if (!cpu_isset(cpu, cpu_callin_map))
+               return -EIO;
+       /* Unleash the CPU! */
+-      set_bit(cpu, &smp_commenced_mask);
+-      while (!test_bit(cpu, &cpu_online_map))
++      cpu_set(cpu, smp_commenced_mask);
++      while (!cpu_isset(cpu, cpu_online_map))
+               mb();
+       return 0;
+ }
+--- linux-2.6.0-test1/arch/i386/Makefile       2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/Makefile      2003-07-19 17:04:05.000000000 -0700
+@@ -85,6 +85,9 @@ mcore-$(CONFIG_X86_ES7000)   := mach-es700
+ # default subarch .h files
+ mflags-y += -Iinclude/asm-i386/mach-default
++mflags-$(CONFIG_KGDB) += -ggdb
++mflags-$(CONFIG_KGDB_MORE) += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
++
+ head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
+ libs-y                                        += arch/i386/lib/
+--- linux-2.6.0-test1/arch/i386/mm/fault.c     2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/mm/fault.c    2003-07-19 17:07:16.000000000 -0700
+@@ -236,6 +236,12 @@ no_context:
+  * Oops. The kernel tried to access some bad page. We'll have to
+  * terminate things with extreme prejudice.
+  */
++#ifdef CONFIG_KGDB
++        if (!user_mode(regs)){
++                kgdb_handle_exception(14,SIGBUS, error_code, regs);
++                return;
++        }
++#endif
+       bust_spinlocks(1);
+@@ -247,6 +253,13 @@ no_context:
+       printk(" printing eip:\n");
+       printk("%08lx\n", regs->eip);
+       asm("movl %%cr3,%0":"=r" (page));
++#ifdef CONFIG_HIGHPMD /* Oh boy. Error reporting is going to blow major goats. */
++      printk(KERN_ALERT "%%cr3 = 0x%lx\n", page);
++      /* Mask off flag bits. It should end up 32B-aligned. */
++      page &= ~(PTRS_PER_PGD*sizeof(pgd_t) - 1);
++      printk(KERN_ALERT "*pdpte = 0x%Lx\n",
++                      pgd_val(((pgd_t *)__va(page))[address >> PGDIR_SHIFT]));
++#else /* !CONFIG_HIGHPMD */
+       page = ((unsigned long *) __va(page))[address >> 22];
+       printk(KERN_ALERT "*pde = %08lx\n", page);
+       /*
+@@ -262,7 +275,8 @@ no_context:
+               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
+               printk(KERN_ALERT "*pte = %08lx\n", page);
+       }
+-#endif
++#endif /* !CONFIG_HIGHPTE */
++#endif /* CONFIG_HIGHPMD */
+       die("Oops", regs, error_code);
+       bust_spinlocks(0);
+       do_exit(SIGKILL);
+@@ -330,8 +344,8 @@ vmalloc_fault:
+                * and redundant with the set_pmd() on non-PAE.
+                */
+-              pmd = pmd_offset(pgd, address);
+-              pmd_k = pmd_offset(pgd_k, address);
++              pmd = pmd_offset_kernel(pgd, address);
++              pmd_k = pmd_offset_kernel(pgd_k, address);
+               if (!pmd_present(*pmd_k))
+                       goto no_context;
+               set_pmd(pmd, *pmd_k);
+--- linux-2.6.0-test1/arch/i386/mm/hugetlbpage.c       2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/i386/mm/hugetlbpage.c      2003-07-19 17:07:16.000000000 -0700
+@@ -87,8 +87,8 @@ static pte_t *huge_pte_alloc(struct mm_s
+       pmd_t *pmd = NULL;
+       pgd = pgd_offset(mm, addr);
+-      pmd = pmd_alloc(mm, pgd, addr);
+-      return (pte_t *) pmd;
++      pmd = pmd_alloc_map(mm, pgd, addr);
++      return (pte_t *)pmd;
+ }
+ static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+@@ -97,8 +97,8 @@ static pte_t *huge_pte_offset(struct mm_
+       pmd_t *pmd = NULL;
+       pgd = pgd_offset(mm, addr);
+-      pmd = pmd_offset(pgd, addr);
+-      return (pte_t *) pmd;
++      pmd = pmd_offset_map_nested(pgd, addr);
++      return (pte_t *)pmd;
+ }
+ static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page, pte_t * page_table, int write_access)
+@@ -145,6 +145,8 @@ int copy_hugetlb_page_range(struct mm_st
+               ptepage = pte_page(entry);
+               get_page(ptepage);
+               set_pte(dst_pte, entry);
++              pmd_unmap(dst_pte);
++              pmd_unmap_nested(src_pte);
+               dst->rss += (HPAGE_SIZE / PAGE_SIZE);
+               addr += HPAGE_SIZE;
+       }
+@@ -182,6 +184,7 @@ follow_hugetlb_page(struct mm_struct *mm
+                       get_page(page);
+                       pages[i] = page;
++                      pmd_unmap_nested(pte);
+               }
+               if (vmas)
+@@ -271,6 +274,7 @@ follow_huge_pmd(struct mm_struct *mm, un
+               page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
+               get_page(page);
+       }
++      pmd_unmap(pmd);
+       return page;
+ }
+ #endif
+@@ -314,6 +318,7 @@ void unmap_hugepage_range(struct vm_area
+               page = pte_page(*pte);
+               huge_page_release(page);
+               pte_clear(pte);
++              pmd_unmap_nested(pte);
+       }
+       mm->rss -= (end - start) >> PAGE_SHIFT;
+       flush_tlb_range(vma, start, end);
+@@ -348,8 +353,10 @@ int hugetlb_prefault(struct address_spac
+                       ret = -ENOMEM;
+                       goto out;
+               }
+-              if (!pte_none(*pte))
++              if (!pte_none(*pte)) {
++                      pmd_unmap(pte);
+                       continue;
++              }
+               idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
+                       + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+@@ -358,16 +365,19 @@ int hugetlb_prefault(struct address_spac
+                       page = alloc_hugetlb_page();
+                       if (!page) {
+                               ret = -ENOMEM;
++                              pmd_unmap(pte);
+                               goto out;
+                       }
+                       ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+                       unlock_page(page);
+                       if (ret) {
+                               free_huge_page(page);
++                              pmd_unmap(pte);
+                               goto out;
+                       }
+               }
+               set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
++              pmd_unmap(pte);
+       }
+ out:
+       spin_unlock(&mm->page_table_lock);
+--- linux-2.6.0-test1/arch/i386/mm/init.c      2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/mm/init.c     2003-07-19 17:07:16.000000000 -0700
+@@ -20,9 +20,6 @@
+ #include <linux/swap.h>
+ #include <linux/smp.h>
+ #include <linux/init.h>
+-#ifdef CONFIG_BLK_DEV_INITRD
+-#include <linux/blk.h>
+-#endif
+ #include <linux/highmem.h>
+ #include <linux/pagemap.h>
+ #include <linux/bootmem.h>
+@@ -59,10 +56,10 @@ static pmd_t * __init one_md_table_init(
+ #ifdef CONFIG_X86_PAE
+       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
+-      if (pmd_table != pmd_offset(pgd, 0)) 
++      if (pmd_table != pmd_offset_kernel(pgd, 0))
+               BUG();
+ #else
+-      pmd_table = pmd_offset(pgd, 0);
++      pmd_table = pmd_offset_kernel(pgd, 0);
+ #endif
+       return pmd_table;
+@@ -113,7 +110,7 @@ static void __init page_table_range_init
+               if (pgd_none(*pgd)) 
+                       one_md_table_init(pgd);
+-              pmd = pmd_offset(pgd, vaddr);
++              pmd = pmd_offset_kernel(pgd, vaddr);
+               for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
+                       if (pmd_none(*pmd)) 
+                               one_page_table_init(pmd);
+@@ -194,7 +191,7 @@ pte_t *kmap_pte;
+ pgprot_t kmap_prot;
+ #define kmap_get_fixmap_pte(vaddr)                                    \
+-      pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
++      pte_offset_kernel(pmd_offset_kernel(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+ void __init kmap_init(void)
+ {
+@@ -218,7 +215,7 @@ void __init permanent_kmaps_init(pgd_t *
+       page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+       pgd = swapper_pg_dir + pgd_index(vaddr);
+-      pmd = pmd_offset(pgd, vaddr);
++      pmd = pmd_offset_kernel(pgd, vaddr);
+       pte = pte_offset_kernel(pmd, vaddr);
+       pkmap_page_table = pte; 
+ }
+@@ -512,20 +509,19 @@ void __init mem_init(void)
+ #endif
+ }
+-#ifdef CONFIG_X86_PAE
+-struct kmem_cache_s *pae_pgd_cachep;
++kmem_cache_t *pgd_cache;
+ void __init pgtable_cache_init(void)
+ {
+-        /*
+-         * PAE pgds must be 16-byte aligned:
+-         */
+-        pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
+-                SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
+-        if (!pae_pgd_cachep)
+-                panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
++      pgd_cache = kmem_cache_create("pgd",
++                              PTRS_PER_PGD*sizeof(pgd_t),
++                              0,
++                              SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
++                              pgd_ctor,
++                              PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
++      if (!pgd_cache)
++              panic("pgtable_cache_init(): Cannot create pgd cache");
+ }
+-#endif
+ /*
+  * This function cannot be __init, since exceptions don't work in that
+@@ -565,7 +561,7 @@ void free_initmem(void)
+               free_page(addr);
+               totalram_pages++;
+       }
+-      printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
++      printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
+ }
+ #ifdef CONFIG_BLK_DEV_INITRD
+--- linux-2.6.0-test1/arch/i386/mm/ioremap.c   2003-06-14 12:18:04.000000000 -0700
++++ 25/arch/i386/mm/ioremap.c  2003-07-19 17:07:16.000000000 -0700
+@@ -82,7 +82,7 @@ static int remap_area_pages(unsigned lon
+       spin_lock(&init_mm.page_table_lock);
+       do {
+               pmd_t *pmd;
+-              pmd = pmd_alloc(&init_mm, dir, address);
++              pmd = pmd_alloc_kernel(&init_mm, dir, address);
+               error = -ENOMEM;
+               if (!pmd)
+                       break;
+--- linux-2.6.0-test1/arch/i386/mm/pageattr.c  2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/i386/mm/pageattr.c 2003-07-19 17:07:16.000000000 -0700
+@@ -23,7 +23,7 @@ static inline pte_t *lookup_address(unsi
+       pmd_t *pmd;
+       if (pgd_none(*pgd))
+               return NULL;
+-      pmd = pmd_offset(pgd, address);                
++      pmd = pmd_offset_kernel(pgd, address);
+       if (pmd_none(*pmd))
+               return NULL;
+       if (pmd_large(*pmd))
+@@ -67,19 +67,22 @@ static void flush_kernel_map(void *dummy
+ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) 
+ { 
++      struct page *page;
++      unsigned long flags;
++
+       set_pte_atomic(kpte, pte);      /* change init_mm */
+-#ifndef CONFIG_X86_PAE
+-      {
+-              struct list_head *l;
+-              spin_lock(&mmlist_lock);
+-              list_for_each(l, &init_mm.mmlist) { 
+-                      struct mm_struct *mm = list_entry(l, struct mm_struct, mmlist);
+-                      pmd_t *pmd = pmd_offset(pgd_offset(mm, address), address);
+-                      set_pte_atomic((pte_t *)pmd, pte);
+-              } 
+-              spin_unlock(&mmlist_lock);
++      if (PTRS_PER_PMD > 1)
++              return;
++
++      spin_lock_irqsave(&pgd_lock, flags);
++      list_for_each_entry(page, &pgd_list, lru) {
++              pgd_t *pgd;
++              pmd_t *pmd;
++              pgd = (pgd_t *)page_address(page) + pgd_index(address);
++              pmd = pmd_offset_kernel(pgd, address);
++              set_pte_atomic((pte_t *)pmd, pte);
+       }
+-#endif
++      spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+ /* 
+@@ -89,7 +92,7 @@ static void set_pmd_pte(pte_t *kpte, uns
+ static inline void revert_page(struct page *kpte_page, unsigned long address)
+ {
+       pte_t *linear = (pte_t *) 
+-              pmd_offset(pgd_offset(&init_mm, address), address);
++              pmd_offset_kernel(pgd_offset_k(address), address);
+       set_pmd_pte(linear,  address,
+                   pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
+                           PAGE_KERNEL_LARGE));
+--- linux-2.6.0-test1/arch/i386/mm/pgtable.c   2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/i386/mm/pgtable.c  2003-07-19 17:07:16.000000000 -0700
+@@ -12,6 +12,7 @@
+ #include <linux/highmem.h>
+ #include <linux/slab.h>
+ #include <linux/pagemap.h>
++#include <linux/spinlock.h>
+ #include <asm/system.h>
+ #include <asm/pgtable.h>
+@@ -69,7 +70,7 @@ static void set_pte_pfn(unsigned long va
+               BUG();
+               return;
+       }
+-      pmd = pmd_offset(pgd, vaddr);
++      pmd = pmd_offset_kernel(pgd, vaddr);
+       if (pmd_none(*pmd)) {
+               BUG();
+               return;
+@@ -109,7 +110,7 @@ void set_pmd_pfn(unsigned long vaddr, un
+               printk ("set_pmd_pfn: pgd_none\n");
+               return; /* BUG(); */
+       }
+-      pmd = pmd_offset(pgd, vaddr);
++      pmd = pmd_offset_kernel(pgd, vaddr);
+       set_pmd(pmd, pfn_pmd(pfn, flags));
+       /*
+        * It's enough to flush this one mapping.
+@@ -151,61 +152,89 @@ struct page *pte_alloc_one(struct mm_str
+       return pte;
+ }
+-#ifdef CONFIG_X86_PAE
++/*
++ * List of all pgd's needed for non-PAE so it can invalidate entries
++ * in both cached and uncached pgd's; not needed for PAE since the
++ * kernel pmd is shared. If PAE were not to share the pmd a similar
++ * tactic would be needed. This is essentially codepath-based locking
++ * against pageattr.c; it is the unique case in which a valid change
++ * of kernel pagetables can't be lazily synchronized by vmalloc faults.
++ * vmalloc faults work because attached pagetables are never freed.
++ * If the locking proves to be non-performant, a ticketing scheme with
++ * checks at dup_mmap(), exec(), and other mmlist addition points
++ * could be used. The locking scheme was chosen on the basis of
++ * manfred's recommendations and having no core impact whatsoever.
++ * -- wli
++ */
++spinlock_t pgd_lock = SPIN_LOCK_UNLOCKED;
++LIST_HEAD(pgd_list);
+-pgd_t *pgd_alloc(struct mm_struct *mm)
++void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+ {
+-      int i;
+-      pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL);
++      unsigned long flags;
+-      if (pgd) {
+-              for (i = 0; i < USER_PTRS_PER_PGD; i++) {
+-                      unsigned long pmd = __get_free_page(GFP_KERNEL);
+-                      if (!pmd)
+-                              goto out_oom;
+-                      clear_page(pmd);
+-                      set_pgd(pgd + i, __pgd(1 + __pa(pmd)));
+-              }
+-              memcpy(pgd + USER_PTRS_PER_PGD,
++      if (PTRS_PER_PMD == 1)
++              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));
+-      }
+-      return pgd;
+-out_oom:
+-      for (i--; i >= 0; i--)
+-              free_page((unsigned long)__va(pgd_val(pgd[i])-1));
+-      kmem_cache_free(pae_pgd_cachep, pgd);
+-      return NULL;
++
++      if (PTRS_PER_PMD > 1)
++              return;
++
++      list_add(&virt_to_page(pgd)->lru, &pgd_list);
++      spin_unlock_irqrestore(&pgd_lock, flags);
++      memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
+ }
+-void pgd_free(pgd_t *pgd)
++/* never called when PTRS_PER_PMD > 1 */
++void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+ {
+-      int i;
++      unsigned long flags; /* can be called from interrupt context */
+-      for (i = 0; i < USER_PTRS_PER_PGD; i++)
+-              free_page((unsigned long)__va(pgd_val(pgd[i])-1));
+-      kmem_cache_free(pae_pgd_cachep, pgd);
++      spin_lock_irqsave(&pgd_lock, flags);
++      list_del(&virt_to_page(pgd)->lru);
++      spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+-#else
+-
+ pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+-      pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
++      int i;
++      pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
+-      if (pgd) {
+-              memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+-              memcpy(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 || !pgd)
++              return pgd;
++
++      for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
++              struct page *pmd;
++#ifdef CONFIG_HIGHPMD
++              pmd = alloc_page(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT);
++#else
++              pmd = alloc_page(GFP_KERNEL|__GFP_REPEAT);
++#endif
++              if (!pmd)
++                      goto out_oom;
++              clear_highpage(pmd);
++              set_pgd(&pgd[i], __pgd(1ULL | (u64)page_to_pfn(pmd) << PAGE_SHIFT));
+       }
+       return pgd;
++
++out_oom:
++      for (i--; i >= 0; i--)
++              __free_page(pgd_page(pgd[i]));
++      kmem_cache_free(pgd_cache, pgd);
++      return NULL;
+ }
+ void pgd_free(pgd_t *pgd)
+ {
+-      free_page((unsigned long)pgd);
+-}
+-
+-#endif /* CONFIG_X86_PAE */
++      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)
++                      __free_page(pgd_page(pgd[i]));
++      /* in the non-PAE case, clear_page_tables() clears user pgd entries */
++      kmem_cache_free(pgd_cache, pgd);
++}
+--- linux-2.6.0-test1/arch/i386/pci/legacy.c   2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/i386/pci/legacy.c  2003-07-19 17:03:49.000000000 -0700
+@@ -24,7 +24,7 @@ static void __devinit pcibios_fixup_peer
+               for (devfn = 0; devfn < 256; devfn += 8) {
+                       if (!raw_pci_ops->read(0, n, devfn, PCI_VENDOR_ID, 2, &l) &&
+                           l != 0x0000 && l != 0xffff) {
+-                              DBG("Found device at %02x:%02x [%04x]\n", n, dev->devfn, l);
++                              DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
+                               printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
+                               pci_scan_bus(n, &pci_root_ops, NULL);
+                               break;
+--- linux-2.6.0-test1/arch/i386/pci/visws.c    2003-06-14 12:18:29.000000000 -0700
++++ 25/arch/i386/pci/visws.c   2003-07-19 17:03:49.000000000 -0700
+@@ -17,7 +17,7 @@
+ int broken_hp_bios_irq9;
+-extern struct pci_ops pci_direct_conf1;
++extern struct pci_raw_ops pci_direct_conf1;
+ static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; }
+@@ -101,8 +101,9 @@ static int __init pcibios_init(void)
+       printk(KERN_INFO "PCI: Lithium bridge A bus: %u, "
+               "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0);
+-      pci_scan_bus(pci_bus0, &pci_direct_conf1, NULL);
+-      pci_scan_bus(pci_bus1, &pci_direct_conf1, NULL);
++      raw_pci_ops = &pci_direct_conf1;
++      pci_scan_bus(pci_bus0, &pci_root_ops, NULL);
++      pci_scan_bus(pci_bus1, &pci_root_ops, NULL);
+       pci_fixup_irqs(visws_swizzle, visws_map_irq);
+       pcibios_resource_survey();
+       return 0;
+--- linux-2.6.0-test1/arch/ia64/hp/sim/simscsi.c       2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/ia64/hp/sim/simscsi.c      2003-07-19 17:03:49.000000000 -0700
+@@ -9,7 +9,7 @@
+  * 99/12/18 David Mosberger   Added support for READ10/WRITE10 needed by linux v2.3.33
+  */
+ #include <linux/config.h>
+-#include <linux/blk.h>
++#include <linux/blkdev.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+--- linux-2.6.0-test1/arch/ia64/ia32/ia32_ioctl.c      2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/ia64/ia32/ia32_ioctl.c     2003-07-19 17:03:49.000000000 -0700
+@@ -52,7 +52,7 @@
+ #include <linux/raw.h>
+ #include <linux/smb_fs.h>
+ #include <linux/blkpg.h>
+-#include <linux/blk.h>
++#include <linux/blkdev.h>
+ #include <linux/elevator.h>
+ #include <linux/rtc.h>
+ #include <linux/pci.h>
+--- linux-2.6.0-test1/arch/ia64/kernel/acpi.c  2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/ia64/kernel/acpi.c 2003-07-19 17:03:49.000000000 -0700
+@@ -720,7 +720,7 @@ acpi_register_irq (u32 gsi, u32 polarity
+ {
+       int vector = 0;
+-      if (acpi_madt->flags.pcat_compat && (gsi < 16))
++      if (has_8259 && (gsi < 16))
+               return isa_irq_to_vector(gsi);
+       if (!iosapic_register_intr)
+--- linux-2.6.0-test1/arch/ia64/kernel/entry.S 2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/ia64/kernel/entry.S        2003-07-19 17:03:49.000000000 -0700
+@@ -61,7 +61,17 @@ ENTRY(ia64_execve)
+       mov out2=in2                    // envp
+       add out3=16,sp                  // regs
+       br.call.sptk.many rp=sys_execve
+-.ret0:        cmp4.ge p6,p7=r8,r0
++.ret0:
++#ifdef CONFIG_IA32_SUPPORT
++      /*
++       * Check if we're returning to ia32 mode. If so, we need to restore ia32 registers
++       * from pt_regs.
++       */
++      adds r16=PT(CR_IPSR)+16,sp
++      ;;
++      ld8 r16=[r16]
++#endif
++      cmp4.ge p6,p7=r8,r0
+       mov ar.pfs=loc1                 // restore ar.pfs
+       sxt4 r8=r8                      // return 64-bit result
+       ;;
+@@ -89,6 +99,12 @@ ENTRY(ia64_execve)
+       ldf.fill f23=[sp];      ldf.fill f24=[sp];      mov f25=f0
+       ldf.fill f26=[sp];      ldf.fill f27=[sp];      mov f28=f0
+       ldf.fill f29=[sp];      ldf.fill f30=[sp];      mov f31=f0
++#ifdef CONFIG_IA32_SUPPORT
++      tbit.nz p6,p0=r16, IA64_PSR_IS_BIT
++      movl loc0=ia64_ret_from_ia32_execve
++      ;;
++(p6)  mov rp=loc0
++#endif
+       br.ret.sptk.many rp
+ END(ia64_execve)
+@@ -688,7 +704,7 @@ GLOBAL_ENTRY(ia64_leave_syscall)
+       mov b7=r0               // clear b7
+       ;;
+ (pUStk) st1 [r14]=r3
+-      movl r17=THIS_CPU(ia64_phys_stacked_size_p8)
++      addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
+       ;;
+       mov r16=ar.bsp          // get existing backing store pointer
+       srlz.i                  // ensure interruption collection is off
+@@ -701,6 +717,19 @@ GLOBAL_ENTRY(ia64_leave_syscall)
+       br.cond.sptk.many rbs_switch
+ END(ia64_leave_syscall)
++#ifdef CONFIG_IA32_SUPPORT
++GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
++      PT_REGS_UNWIND_INFO(0)
++      adds r2=PT(R8)+16,sp                    // r2 = &pt_regs.r8
++      adds r3=PT(R10)+16,sp                   // r3 = &pt_regs.r10
++      ;;
++      .mem.offset 0,0
++      st8.spill [r2]=r8       // store return value in slot for r8 and set unat bit
++      .mem.offset 8,0
++      st8.spill [r3]=r0       // clear error indication in slot for r10 and set unat bit
++END(ia64_ret_from_ia32_execve_syscall)
++      // fall through
++#endif /* CONFIG_IA32_SUPPORT */
+ GLOBAL_ENTRY(ia64_leave_kernel)
+       PT_REGS_UNWIND_INFO(0)
+       /*
+@@ -841,7 +870,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
+       shr.u r18=r19,16        // get byte size of existing "dirty" partition
+       ;;
+       mov r16=ar.bsp          // get existing backing store pointer
+-      movl r17=THIS_CPU(ia64_phys_stacked_size_p8)
++      addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
+       ;;
+       ld4 r17=[r17]           // r17 = cpu_data->phys_stacked_size_p8
+ (pKStk)       br.cond.dpnt skip_rbs_switch
+--- linux-2.6.0-test1/arch/ia64/kernel/fsys.S  2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/ia64/kernel/fsys.S 2003-07-19 17:03:49.000000000 -0700
+@@ -165,7 +165,7 @@ ENTRY(fsys_gettimeofday)
+       .altrp b6
+       .body
+       add r9=TI_FLAGS+IA64_TASK_SIZE,r16
+-      movl r3=THIS_CPU(cpu_info)
++      addl r3=THIS_CPU(cpu_info),r0
+       mov.m r31=ar.itc                // put time stamp into r31 (ITC) == now         (35 cyc)
+ #ifdef CONFIG_SMP
+@@ -177,7 +177,7 @@ ENTRY(fsys_gettimeofday)
+       movl r19=xtime                  // xtime is a timespec struct
+       ld8 r10=[r10]                   // r10 <- __per_cpu_offset[0]
+-      movl r21=THIS_CPU(cpu_info)
++      addl r21=THIS_CPU(cpu_info),r0
+       ;;
+       add r10=r21, r10                // r10 <- &cpu_data(time_keeper_id)
+       tbit.nz p8,p0 = r2, IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT
+--- linux-2.6.0-test1/arch/ia64/kernel/ia64_ksyms.c    2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/ia64/kernel/ia64_ksyms.c   2003-07-19 17:03:49.000000000 -0700
+@@ -64,9 +64,10 @@ EXPORT_SYMBOL(ia64_pfn_valid);
+ #endif
+ #include <asm/processor.h>
+-EXPORT_SYMBOL(cpu_info__per_cpu);
++EXPORT_SYMBOL(per_cpu__cpu_info);
+ #ifdef CONFIG_SMP
+ EXPORT_SYMBOL(__per_cpu_offset);
++EXPORT_SYMBOL(per_cpu__local_per_cpu_offset);
+ #endif
+ EXPORT_SYMBOL(kernel_thread);
+--- linux-2.6.0-test1/arch/ia64/kernel/init_task.c     2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/ia64/kernel/init_task.c    2003-07-19 17:03:49.000000000 -0700
+@@ -2,7 +2,7 @@
+  * This is where we statically allocate and initialize the initial
+  * task.
+  *
+- * Copyright (C) 1999, 2002 Hewlett-Packard Co
++ * Copyright (C) 1999, 2002-2003 Hewlett-Packard Co
+  *    David Mosberger-Tang <davidm@hpl.hp.com>
+  */
+@@ -34,7 +34,7 @@ static union {
+               struct thread_info thread_info;
+       } s;
+       unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
+-} init_task_mem __attribute__((section(".data.init_task"))) = {{
++} init_task_mem asm ("init_task_mem") __attribute__((section(".data.init_task"))) = {{
+       .task =         INIT_TASK(init_task_mem.s.task),
+       .thread_info =  INIT_THREAD_INFO(init_task_mem.s.task)
+ }};
+--- linux-2.6.0-test1/arch/ia64/kernel/iosapic.c       2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/ia64/kernel/iosapic.c      2003-07-19 17:04:06.000000000 -0700
+@@ -274,7 +274,7 @@ unmask_irq (unsigned int irq)
+ static void
+-iosapic_set_affinity (unsigned int irq, unsigned long mask)
++iosapic_set_affinity (unsigned int irq, cpumask_t mask)
+ {
+ #ifdef CONFIG_SMP
+       unsigned long flags;
+@@ -287,12 +287,10 @@ iosapic_set_affinity (unsigned int irq, 
+       irq &= (~IA64_IRQ_REDIRECTED);
+       vec = irq_to_vector(irq);
+-      mask &= cpu_online_map;
+-
+-      if (!mask || vec >= IA64_NUM_VECTORS)
++      if (cpus_empty(mask) || vec >= IA64_NUM_VECTORS)
+               return;
+-      dest = cpu_physical_id(ffz(~mask));
++      dest = cpu_physical_id(first_cpu(mask));
+       rte_index = iosapic_intr_info[vec].rte_index;
+       addr = iosapic_intr_info[vec].addr;
+@@ -717,6 +715,7 @@ iosapic_parse_prt (void)
+                       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
+                                     IOSAPIC_LEVEL);
+               }
++              entry->irq = vector;
+               snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
+                        entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin);
+--- linux-2.6.0-test1/arch/ia64/kernel/irq.c   2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/ia64/kernel/irq.c  2003-07-19 17:04:06.000000000 -0700
+@@ -898,13 +898,14 @@ int setup_irq(unsigned int irq, struct i
+ static struct proc_dir_entry * root_irq_dir;
+ static struct proc_dir_entry * irq_dir [NR_IRQS];
+-#define HEX_DIGITS 8
++#define HEX_DIGITS (2*sizeof(cpumask_t))
+-static unsigned int parse_hex_value (const char *buffer,
+-              unsigned long count, unsigned long *ret)
++static unsigned int parse_hex_value(const char *buffer,
++              unsigned long count, cpumask_t *ret)
+ {
+-      unsigned char hexnum [HEX_DIGITS];
+-      unsigned long value, i;
++      unsigned char hexnum[HEX_DIGITS];
++      cpumask_t value = CPU_MASK_NONE;
++      unsigned long i;
+       if (!count)
+               return -EINVAL;
+@@ -917,10 +918,9 @@ static unsigned int parse_hex_value (con
+        * Parse the first 8 characters as a hex string, any non-hex char
+        * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+        */
+-      value = 0;
+-
+       for (i = 0; i < count; i++) {
+               unsigned int c = hexnum[i];
++              int k;
+               switch (c) {
+                       case '0' ... '9': c -= '0'; break;
+@@ -929,7 +929,10 @@ static unsigned int parse_hex_value (con
+               default:
+                       goto out;
+               }
+-              value = (value << 4) | c;
++              cpus_shift_left(value, value, 4);
++              for (k = 0; k < 4; ++k)
++                      if (test_bit(k, (unsigned long *)&c))
++                              cpu_set(k, value);
+       }
+ out:
+       *ret = value;
+@@ -940,12 +943,15 @@ out:
+ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+-static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
++static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
++
+ static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
+ void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
+ {
+-      unsigned long mask = 1UL<<cpu_logical_id(hwid);
++      cpumask_t mask = CPU_MASK_NONE;
++
++      cpu_set(cpu_logical_id(hwid), mask);
+       if (irq < NR_IRQS) {
+               irq_affinity[irq] = mask;
+@@ -956,10 +962,21 @@ void set_irq_affinity_info (unsigned int
+ static int irq_affinity_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      if (count < HEX_DIGITS+3)
++      int k, len;
++      cpumask_t tmp = irq_affinity[(long)data];
++
++      if (count < HEX_DIGITS+1)
+               return -EINVAL;
+-      return sprintf (page, "%s%08lx\n", irq_redir[(unsigned long)data] ? "r " : "",
+-                      irq_affinity[(unsigned long)data]);
++
++      len = 0;
++      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
++              int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
++              len += j;
++              page += j;
++              cpus_shift_right(tmp, tmp, 16);
++      }
++      len += sprintf(page, "\n");
++      return len;
+ }
+ static int irq_affinity_write_proc (struct file *file, const char *buffer,
+@@ -967,7 +984,7 @@ static int irq_affinity_write_proc (stru
+ {
+       unsigned int irq = (unsigned long) data;
+       int full_count = count, err;
+-      unsigned long new_value;
++      cpumask_t new_value, tmp;
+       const char *buf = buffer;
+       irq_desc_t *desc = irq_descp(irq);
+       int redir;
+@@ -991,7 +1008,8 @@ static int irq_affinity_write_proc (stru
+        * way to make the system unusable accidentally :-) At least
+        * one online CPU still has to be targeted.
+        */
+-      if (!(new_value & cpu_online_map))
++      cpus_and(tmp, new_value, cpu_online_map);
++      if (cpus_empty(tmp))
+               return -EINVAL;
+       desc->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value);
+@@ -1003,18 +1021,28 @@ static int irq_affinity_write_proc (stru
+ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      unsigned long *mask = (unsigned long *) data;
++      cpumask_t *mask = (cpumask_t *)data;
++      int k, len = 0;
++
+       if (count < HEX_DIGITS+1)
+               return -EINVAL;
+-      return sprintf (page, "%08lx\n", *mask);
++
++      for (k = 0; k < sizeof(cpumask_t)/sizeof(unsigned long); ++k) {
++              int j = sprintf(page, "%04hx", (u16)cpus_coerce(*mask));
++              len += j;
++              page += j;
++              cpus_shift_right(*mask, *mask, 16);
++      }
++      len += sprintf(page, "\n");
++      return len;
+ }
+ static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+                                       unsigned long count, void *data)
+ {
+-      unsigned long *mask = (unsigned long *) data;
+-      int full_count = count, err;
+-      unsigned long new_value;
++      cpumask_t *mask = (cpumask_t *)data;
++      unsigned long full_count = count, err;
++      cpumask_t new_value;
+       err = parse_hex_value(buffer, count, &new_value);
+       if (err)
+@@ -1058,7 +1086,7 @@ static void register_irq_proc (unsigned 
+ #endif
+ }
+-unsigned long prof_cpu_mask = -1;
++cpumask_t prof_cpu_mask = CPU_MASK_ALL;
+ void init_irq_proc (void)
+ {
+--- linux-2.6.0-test1/arch/ia64/kernel/module.c        2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/ia64/kernel/module.c       2003-07-19 17:03:49.000000000 -0700
+@@ -164,7 +164,7 @@ static int
+ apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
+ {
+       if (slot(insn) != 2) {
+-              printk(KERN_ERR "%s: illegal slot number %d for IMM64\n",
++              printk(KERN_ERR "%s: invalid slot number %d for IMM64\n",
+                      mod->name, slot(insn));
+               return 0;
+       }
+@@ -176,7 +176,7 @@ static int
+ apply_imm60 (struct module *mod, struct insn *insn, uint64_t val)
+ {
+       if (slot(insn) != 2) {
+-              printk(KERN_ERR "%s: illegal slot number %d for IMM60\n",
++              printk(KERN_ERR "%s: invalid slot number %d for IMM60\n",
+                      mod->name, slot(insn));
+               return 0;
+       }
+--- linux-2.6.0-test1/arch/ia64/kernel/perfmon.c       2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/ia64/kernel/perfmon.c      2003-07-19 17:04:06.000000000 -0700
+@@ -221,14 +221,6 @@
+ #define PFM_REG_RETFLAG_SET(flags, val)       do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
+-#ifdef CONFIG_SMP
+-#define PFM_CPU_ONLINE_MAP    cpu_online_map
+-#define cpu_is_online(i)      (PFM_CPU_ONLINE_MAP & (1UL << i))
+-#else
+-#define PFM_CPU_ONLINE_MAP     1UL
+-#define cpu_is_online(i)      (i==0)
+-#endif
+-
+ /*
+  * cmp0 must be the value of pmc0
+  */
+@@ -566,7 +558,7 @@ static struct vm_operations_struct pfm_v
+ #define pfm_wait_task_inactive(t)     wait_task_inactive(t)
+-#define pfm_get_cpu_var(v)            __get_cpu_var(v)
++#define pfm_get_cpu_var(v)            __ia64_per_cpu_var(v)
+ #define pfm_get_cpu_data(a,b)         per_cpu(a, b)
+ typedef       irqreturn_t     pfm_irq_handler_t;
+ #define PFM_IRQ_HANDLER_RET(v)        do {  \
+@@ -5354,7 +5346,7 @@ pfm_proc_info(char *page)
+               p += sprintf(p, "ovfl_mask                 : 0x%lx\n", pmu_conf.ovfl_val);
+       for(i=0; i < NR_CPUS; i++) {
+-              if (cpu_is_online(i) == 0) continue;
++              if (cpu_online(i) == 0) continue;
+               p += sprintf(p, "CPU%-2d overflow intrs      : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count);
+               p += sprintf(p, "CPU%-2d overflow cycles     : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles);
+               p += sprintf(p, "CPU%-2d overflow min        : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles_min);
+@@ -5372,7 +5364,7 @@ pfm_proc_info(char *page)
+               p += sprintf(p, "CPU%-2d activations         : %lu\n", i, pfm_get_cpu_data(pmu_activation_number,i));
+       }
+-      if (hweight64(PFM_CPU_ONLINE_MAP) == 1)
++      if (num_online_cpus() == 1)
+       {
+               psr = pfm_get_psr();
+               ia64_srlz_d();
+--- linux-2.6.0-test1/arch/ia64/kernel/ptrace.c        2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/ia64/kernel/ptrace.c       2003-07-19 17:03:49.000000000 -0700
+@@ -42,7 +42,7 @@
+       (IA64_PSR_UM | IA64_PSR_DB | IA64_PSR_IS | IA64_PSR_ID | IA64_PSR_DD | IA64_PSR_RI)
+ #define IPSR_READ_MASK        IPSR_WRITE_MASK
+-#define PTRACE_DEBUG  1
++#define PTRACE_DEBUG  0
+ #if PTRACE_DEBUG
+ # define dprintk(format...)   printk(format)
+--- linux-2.6.0-test1/arch/ia64/kernel/setup.c 2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/ia64/kernel/setup.c        2003-07-19 17:04:07.000000000 -0700
+@@ -56,6 +56,7 @@ unsigned long __per_cpu_offset[NR_CPUS];
+ #endif
+ DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
++DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
+ DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
+ unsigned long ia64_cycles_per_usec;
+ struct ia64_boot_param *ia64_boot_param;
+@@ -558,7 +559,7 @@ static void *
+ c_start (struct seq_file *m, loff_t *pos)
+ {
+ #ifdef CONFIG_SMP
+-      while (*pos < NR_CPUS && !(cpu_online_map & (1UL << *pos)))
++      while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map))
+               ++*pos;
+ #endif
+       return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
+@@ -709,6 +710,8 @@ cpu_init (void)
+                       memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
+                       __per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
+                       cpu_data += PERCPU_PAGE_SIZE;
++
++                      per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
+               }
+       }
+       cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+@@ -716,19 +719,18 @@ cpu_init (void)
+       cpu_data = __phys_per_cpu_start;
+ #endif /* !CONFIG_SMP */
+-      cpu_info = cpu_data + ((char *) &__get_cpu_var(cpu_info) - __per_cpu_start);
+-#ifdef CONFIG_NUMA
+-      cpu_info->node_data = get_node_data_ptr();
+-#endif
+-
+       get_max_cacheline_size();
+       /*
+        * We can't pass "local_cpu_data" to identify_cpu() because we haven't called
+        * ia64_mmu_init() yet.  And we can't call ia64_mmu_init() first because it
+        * depends on the data returned by identify_cpu().  We break the dependency by
+-       * accessing cpu_data() the old way, through identity mapped space.
++       * accessing cpu_data() through the canonical per-CPU address.
+        */
++      cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start);
++#ifdef CONFIG_NUMA
++      cpu_info->node_data = get_node_data_ptr();
++#endif
+       identify_cpu(cpu_info);
+ #ifdef CONFIG_MCKINLEY
+--- linux-2.6.0-test1/arch/ia64/kernel/smpboot.c       2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/ia64/kernel/smpboot.c      2003-07-19 17:04:07.000000000 -0700
+@@ -79,13 +79,13 @@ int cpucount;
+ task_t *task_for_booting_cpu;
+ /* Bitmask of currently online CPUs */
+-volatile unsigned long cpu_online_map;
+-unsigned long phys_cpu_present_map;
++cpumask_t cpu_online_map;
++cpumask_t phys_cpu_present_map;
+ /* which logical CPU number maps to which CPU (physical APIC ID) */
+ volatile int ia64_cpu_to_sapicid[NR_CPUS];
+-static volatile unsigned long cpu_callin_map;
++static volatile cpumask_t cpu_callin_map;
+ struct smp_boot_data smp_boot_data __initdata;
+@@ -282,7 +282,7 @@ smp_callin (void)
+       cpuid = smp_processor_id();
+       phys_id = hard_smp_processor_id();
+-      if (test_and_set_bit(cpuid, &cpu_online_map)) {
++      if (cpu_test_and_set(cpuid, cpu_online_map)) {
+               printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
+                      phys_id, cpuid);
+               BUG();
+@@ -327,7 +327,7 @@ smp_callin (void)
+       /*
+        * Allow the master to continue.
+        */
+-      set_bit(cpuid, &cpu_callin_map);
++      cpu_set(cpuid, cpu_callin_map);
+       Dprintk("Stack on CPU %d at about %p\n",cpuid, &cpuid);
+ }
+@@ -391,19 +391,19 @@ do_boot_cpu (int sapicid, int cpu)
+        */
+       Dprintk("Waiting on callin_map ...");
+       for (timeout = 0; timeout < 100000; timeout++) {
+-              if (test_bit(cpu, &cpu_callin_map))
++              if (cpu_isset(cpu, cpu_callin_map))
+                       break;  /* It has booted */
+               udelay(100);
+       }
+       Dprintk("\n");
+-      if (test_bit(cpu, &cpu_callin_map)) {
++      if (cpu_isset(cpu, cpu_callin_map)) {
+               /* number CPUs logically, starting from 1 (BSP is 0) */
+               printk(KERN_INFO "CPU%d: CPU has booted.\n", cpu);
+       } else {
+               printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
+               ia64_cpu_to_sapicid[cpu] = -1;
+-              clear_bit(cpu, &cpu_online_map);  /* was set in smp_callin() */
++              cpu_clear(cpu, cpu_online_map);  /* was set in smp_callin() */
+               return -EINVAL;
+       }
+       return 0;
+@@ -446,13 +446,14 @@ smp_build_cpu_map (void)
+               ia64_cpu_to_sapicid[cpu] = -1;
+       ia64_cpu_to_sapicid[0] = boot_cpu_id;
+-      phys_cpu_present_map = 1;
++      cpus_clear(phys_cpu_present_map);
++      cpu_set(0, phys_cpu_present_map);
+       for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
+               sapicid = smp_boot_data.cpu_phys_id[i];
+               if (sapicid == boot_cpu_id)
+                       continue;
+-              phys_cpu_present_map |= (1UL << cpu);
++              cpu_set(cpu, phys_cpu_present_map);
+               ia64_cpu_to_sapicid[cpu] = sapicid;
+               cpu++;
+       }
+@@ -463,7 +464,7 @@ smp_build_cpu_map (void)
+ /* on which node is each logical CPU (one cacheline even for 64 CPUs) */
+ volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+ /* which logical CPUs are on which nodes */
+-volatile unsigned long node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
++volatile cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+ /*
+  * Build cpu to node mapping and initialize the per node cpu masks.
+@@ -474,7 +475,7 @@ build_cpu_to_node_map (void)
+       int cpu, i, node;
+       for(node=0; node<MAX_NUMNODES; node++)
+-              node_to_cpu_mask[node] = 0;
++              cpus_clear(node_to_cpu_mask[node]);
+       for(cpu = 0; cpu < NR_CPUS; ++cpu) {
+               /*
+                * All Itanium NUMA platforms I know use ACPI, so maybe we
+@@ -492,7 +493,7 @@ build_cpu_to_node_map (void)
+ #endif
+               cpu_to_node_map[cpu] = node;
+               if (node >= 0)
+-                      node_to_cpu_mask[node] |= (1UL << cpu);
++                      cpu_set(cpu, node_to_cpu_mask[node]);
+       }
+ }
+@@ -515,8 +516,8 @@ smp_prepare_cpus (unsigned int max_cpus)
+       /*
+        * We have the boot CPU online for sure.
+        */
+-      set_bit(0, &cpu_online_map);
+-      set_bit(0, &cpu_callin_map);
++      cpu_set(0, cpu_online_map);
++      cpu_set(0, cpu_callin_map);
+       local_cpu_data->loops_per_jiffy = loops_per_jiffy;
+       ia64_cpu_to_sapicid[0] = boot_cpu_id;
+@@ -531,15 +532,18 @@ smp_prepare_cpus (unsigned int max_cpus)
+        */
+       if (!max_cpus) {
+               printk(KERN_INFO "SMP mode deactivated.\n");
+-              cpu_online_map = phys_cpu_present_map = 1;
++              cpus_clear(cpu_online_map);
++              cpus_clear(phys_cpu_present_map);
++              cpu_set(1, cpu_online_map);
++              cpu_set(1, phys_cpu_present_map);
+               return;
+       }
+ }
+ void __devinit smp_prepare_boot_cpu(void)
+ {
+-      set_bit(smp_processor_id(), &cpu_online_map);
+-      set_bit(smp_processor_id(), &cpu_callin_map);
++      cpu_set(smp_processor_id(), cpu_online_map);
++      cpu_set(smp_processor_id(), cpu_callin_map);
+ }
+ void
+--- linux-2.6.0-test1/arch/ia64/kernel/smp.c   2003-06-14 12:18:50.000000000 -0700
++++ 25/arch/ia64/kernel/smp.c  2003-07-19 17:04:07.000000000 -0700
+@@ -72,7 +72,7 @@ static volatile struct call_data_struct 
+ #define IPI_CPU_STOP          1
+ /* This needs to be cacheline aligned because it is written to by *other* CPUs.  */
+-static DEFINE_PER_CPU(__u64, ipi_operation) ____cacheline_aligned;
++static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned;
+ static void
+ stop_this_cpu (void)
+@@ -81,7 +81,7 @@ stop_this_cpu (void)
+       /*
+        * Remove this CPU:
+        */
+-      clear_bit(smp_processor_id(), &cpu_online_map);
++      cpu_clear(smp_processor_id(), cpu_online_map);
+       max_xtp();
+       local_irq_disable();
+       cpu_halt();
+@@ -91,7 +91,7 @@ irqreturn_t
+ handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
+ {
+       int this_cpu = get_cpu();
+-      unsigned long *pending_ipis = &__get_cpu_var(ipi_operation);
++      unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
+       unsigned long ops;
+       /* Count this now; we may make a call that never returns. */
+--- linux-2.6.0-test1/arch/ia64/kernel/time.c  2003-07-13 21:44:34.000000000 -0700
++++ 25/arch/ia64/kernel/time.c 2003-07-19 17:04:07.000000000 -0700
+@@ -40,13 +40,13 @@ unsigned long last_cli_ip;
+ static void
+ do_profile (unsigned long ip)
+ {
+-      extern unsigned long prof_cpu_mask;
++      extern cpumask_t prof_cpu_mask;
+       extern char _stext;
+       if (!prof_buffer)
+               return;
+-      if (!((1UL << smp_processor_id()) & prof_cpu_mask))
++      if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
+               return;
+       ip -= (unsigned long) &_stext;
+@@ -83,12 +83,11 @@ unsigned long
+ itc_get_offset (void)
+ {
+       unsigned long elapsed_cycles, lost = jiffies - wall_jiffies;
+-      unsigned long now, last_tick;
++      unsigned long now = ia64_get_itc(), last_tick;
+       last_tick = (cpu_data(TIME_KEEPER_ID)->itm_next
+                    - (lost + 1)*cpu_data(TIME_KEEPER_ID)->itm_delta);
+-      now = ia64_get_itc();
+       if (unlikely((long) (now - last_tick) < 0)) {
+               printk(KERN_ERR "CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
+                      smp_processor_id(), now, last_tick);
+--- linux-2.6.0-test1/arch/ia64/Makefile       2003-07-02 14:53:12.000000000 -0700
++++ 25/arch/ia64/Makefile      2003-07-19 17:03:49.000000000 -0700
+@@ -66,8 +66,7 @@ core-$(CONFIG_IA64_SGI_SN2)  += arch/ia64
+ drivers-$(CONFIG_PCI)         += arch/ia64/pci/
+ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
+ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
+-drivers-$(CONFIG_IA64_GENERIC)        += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ \
+-                                 arch/ia64/sn/
++drivers-$(CONFIG_IA64_GENERIC)        += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/
+ boot := arch/ia64/boot
+--- linux-2.6.0-test1/arch/ia64/mm/hugetlbpage.c       2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/ia64/mm/hugetlbpage.c      2003-07-19 17:07:16.000000000