direct-io.hg

changeset 1787:002fc84add90

bitkeeper revision 1.1085 (40f5624559Jpit7H8wc4PzDqjO-E2g)

Initial checkin of Linux 2.6.
author cl349@freefall.cl.cam.ac.uk
date Wed Jul 14 16:41:41 2004 +0000 (2004-07-14)
parents bdafa1768678
children 61599b006364
files .rootkeys BitKeeper/etc/ignore BitKeeper/etc/logging_ok linux-2.6.7-xen-sparse/arch/xen/Kconfig linux-2.6.7-xen-sparse/arch/xen/Kconfig.drivers linux-2.6.7-xen-sparse/arch/xen/Makefile linux-2.6.7-xen-sparse/arch/xen/boot/Makefile linux-2.6.7-xen-sparse/arch/xen/defconfig linux-2.6.7-xen-sparse/arch/xen/i386/Kconfig linux-2.6.7-xen-sparse/arch/xen/i386/Makefile linux-2.6.7-xen-sparse/arch/xen/i386/kernel/Makefile linux-2.6.7-xen-sparse/arch/xen/i386/kernel/cpu/Makefile linux-2.6.7-xen-sparse/arch/xen/i386/kernel/cpu/common.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/entry.S linux-2.6.7-xen-sparse/arch/xen/i386/kernel/evtchn.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/head.S linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/signal.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/sysenter.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/Makefile linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/vmlinux.lds.S linux-2.6.7-xen-sparse/arch/xen/i386/kernel/vsyscall.S linux-2.6.7-xen-sparse/arch/xen/i386/kernel/vsyscall.lds linux-2.6.7-xen-sparse/arch/xen/i386/mm/Makefile linux-2.6.7-xen-sparse/arch/xen/i386/mm/fault.c linux-2.6.7-xen-sparse/arch/xen/i386/mm/hypervisor.c linux-2.6.7-xen-sparse/arch/xen/i386/mm/init.c linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c linux-2.6.7-xen-sparse/arch/xen/kernel/empty.c linux-2.6.7-xen-sparse/arch/xen/kernel/process.c linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c linux-2.6.7-xen-sparse/drivers/xen/Makefile linux-2.6.7-xen-sparse/drivers/xen/block/Kconfig linux-2.6.7-xen-sparse/drivers/xen/block/Makefile linux-2.6.7-xen-sparse/drivers/xen/block/block.c linux-2.6.7-xen-sparse/drivers/xen/block/block.h linux-2.6.7-xen-sparse/drivers/xen/block/vbd.c linux-2.6.7-xen-sparse/drivers/xen/console/Makefile linux-2.6.7-xen-sparse/drivers/xen/console/console.c linux-2.6.7-xen-sparse/drivers/xen/evtchn/Makefile linux-2.6.7-xen-sparse/drivers/xen/evtchn/evtchn.c linux-2.6.7-xen-sparse/drivers/xen/net/Kconfig linux-2.6.7-xen-sparse/drivers/xen/net/Makefile linux-2.6.7-xen-sparse/drivers/xen/net/network.c linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/desc.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/hypervisor.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/do_timer.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/io_ports.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_mpspec.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_reboot.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_resources.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_time.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_timer.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/msr.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/page.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/param.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgalloc.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/processor.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/ptrace.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/segment.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/setup.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/system.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/timer.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/tlbflush.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/xor.h linux-2.6.7-xen-sparse/include/asm-xen/blkif.h linux-2.6.7-xen-sparse/include/asm-xen/ctrl_if.h linux-2.6.7-xen-sparse/include/asm-xen/domain_controller.h linux-2.6.7-xen-sparse/include/asm-xen/evtchn.h linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/arch-x86_32.h linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/arch-x86_64.h linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/dom0_ops.h linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/event_channel.h linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/hypervisor-if.h linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/physdev.h linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/sched_ctl.h linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/trace.h linux-2.6.7-xen-sparse/include/asm-xen/multicall.h linux-2.6.7-xen-sparse/include/asm-xen/netif.h linux-2.6.7-xen-sparse/include/asm-xen/xen.h
line diff
     1.1 --- a/.rootkeys	Wed Jul 14 15:26:41 2004 +0000
     1.2 +++ b/.rootkeys	Wed Jul 14 16:41:41 2004 +0000
     1.3 @@ -151,6 +151,101 @@ 3f108af5VxPkLv13tXpXgoRKALQtXQ linux-2.4
     1.4  3e5a4e681xMPdF9xCMwpyfuYMySU5g linux-2.4.26-xen-sparse/mm/mremap.c
     1.5  409ba2e7akOFqQUg6Qyg2s28xcXiMg linux-2.4.26-xen-sparse/mm/page_alloc.c
     1.6  3e5a4e683HKVU-sxtagrDasRB8eBVw linux-2.4.26-xen-sparse/mm/swapfile.c
     1.7 +40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.7-xen-sparse/arch/xen/Kconfig
     1.8 +40f56237utH41NPukqHksuNf29IC9A linux-2.6.7-xen-sparse/arch/xen/Kconfig.drivers
     1.9 +40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.7-xen-sparse/arch/xen/Makefile
    1.10 +40f56237JTc60m1FRlUxkUaGSQKrNw linux-2.6.7-xen-sparse/arch/xen/boot/Makefile
    1.11 +40f56237wubfjJKlfIzZlI3ZM2VgGA linux-2.6.7-xen-sparse/arch/xen/defconfig
    1.12 +40f56237Mta0yHNaMS_qtM2rge0qYA linux-2.6.7-xen-sparse/arch/xen/i386/Kconfig
    1.13 +40f56238u2CJdXNpjsZgHBxeVyY-2g linux-2.6.7-xen-sparse/arch/xen/i386/Makefile
    1.14 +40f56238eczveJ86k_4hNxCLRQIF-g linux-2.6.7-xen-sparse/arch/xen/i386/kernel/Makefile
    1.15 +40f56238rXVTJQKbBuXXLH52qEArcg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/cpu/Makefile
    1.16 +40f562385s4lr6Zg92gExe7UQ4A76Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/cpu/common.c
    1.17 +40f56238XDtHSijkAFlbv1PT8Bhw_Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/entry.S
    1.18 +40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.7-xen-sparse/arch/xen/i386/kernel/evtchn.c
    1.19 +40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.7-xen-sparse/arch/xen/i386/kernel/head.S
    1.20 +40f562382aC3_Gt4RG-4ZsfvDRUg3Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c
    1.21 +40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c
    1.22 +40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c
    1.23 +40f56238YQIJoYG2ehDGEcdTgLmGbg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c
    1.24 +40f56238nWMQg7CKbyTy0KJNvCzbtg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/signal.c
    1.25 +40f56238UL9uv78ODDzMwLL9yryeFw linux-2.6.7-xen-sparse/arch/xen/i386/kernel/sysenter.c
    1.26 +40f56238qVGkpO_ycnQA8k03kQzAgA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c
    1.27 +40f56238NzTgeO63RGoxHrW5NQeO3Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/Makefile
    1.28 +40f56238BMqG5PuSHufpjbvp_helBw linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c
    1.29 +40f562389xNa78YBZciUibQjyRU_Lg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c
    1.30 +40f56238qASEI_IOhCKWNuwFKNZrKQ linux-2.6.7-xen-sparse/arch/xen/i386/kernel/vmlinux.lds.S
    1.31 +40f56238JypKAUG01ZojFwH7qnZ5uA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/vsyscall.S
    1.32 +40f56238wi6AdNQjm0RT57bSkwb6hg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/vsyscall.lds
    1.33 +40f56238a3w6-byOzexIlMgni76Lcg linux-2.6.7-xen-sparse/arch/xen/i386/mm/Makefile
    1.34 +40f56238ILx8xlbywNbzTdv5Zr4xXQ linux-2.6.7-xen-sparse/arch/xen/i386/mm/fault.c
    1.35 +40f562383SKvDStdtrvzr5fyCbW4rw linux-2.6.7-xen-sparse/arch/xen/i386/mm/hypervisor.c
    1.36 +40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.7-xen-sparse/arch/xen/i386/mm/init.c
    1.37 +40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c
    1.38 +40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile
    1.39 +40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c
    1.40 +40f56239pYRq5yshPTkv3ujXKc8K6g linux-2.6.7-xen-sparse/arch/xen/kernel/empty.c
    1.41 +40f56239sFcjHiIRmnObRIDF-zaeKQ linux-2.6.7-xen-sparse/arch/xen/kernel/process.c
    1.42 +40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c
    1.43 +40f56239Dp_vMTgz8TEbvo1hjHGc3w linux-2.6.7-xen-sparse/drivers/xen/Makefile
    1.44 +40f56239Sfle6wGv5FS0wjS_HI150A linux-2.6.7-xen-sparse/drivers/xen/block/Kconfig
    1.45 +40f562395atl9x4suKGhPkjqLOXESg linux-2.6.7-xen-sparse/drivers/xen/block/Makefile
    1.46 +40f56239-JNIaTzlviVJohVdoYOUpw linux-2.6.7-xen-sparse/drivers/xen/block/block.c
    1.47 +40f56239y9naBTXe40Pi2J_z3p-d1g linux-2.6.7-xen-sparse/drivers/xen/block/block.h
    1.48 +40f56239BVfPsXBiWQitXgDRtOsiqg linux-2.6.7-xen-sparse/drivers/xen/block/vbd.c
    1.49 +40f56239fsLjvtD8YBRAWphps4FDjg linux-2.6.7-xen-sparse/drivers/xen/console/Makefile
    1.50 +40f56239afE58Oot-9omHGqq4UJ--A linux-2.6.7-xen-sparse/drivers/xen/console/console.c
    1.51 +40f56239KYxO0YabhPzCTeUuln-lnA linux-2.6.7-xen-sparse/drivers/xen/evtchn/Makefile
    1.52 +40f56239DoibTX6R-ZYd3QTXAB8_TA linux-2.6.7-xen-sparse/drivers/xen/evtchn/evtchn.c
    1.53 +40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.7-xen-sparse/drivers/xen/net/Kconfig
    1.54 +40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.7-xen-sparse/drivers/xen/net/Makefile
    1.55 +40f56239vUsbJCS9tGFfRVi1YZlGEg linux-2.6.7-xen-sparse/drivers/xen/net/network.c
    1.56 +40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/desc.h
    1.57 +40f5623anSzpuEHgiNmQ56fIRfCoaQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h
    1.58 +40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h
    1.59 +40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/hypervisor.h
    1.60 +40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h
    1.61 +40f5623am9BzluYFuV6EQfTd-so3dA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/do_timer.h
    1.62 +40f5623adZQ1IZGPxbDXONjyZGYuTA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/io_ports.h
    1.63 +40f5623aKXkBBxgpLx2NcvkncQ1Yyw linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
    1.64 +40f5623aMQZoYuf4ml9v69N3gu8ing linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_mpspec.h
    1.65 +40f5623a8LroVMnZ5YRzJJmIc-zHlw linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_reboot.h
    1.66 +40f5623an3wOvFKmpIvqSxQfWzklVQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_resources.h
    1.67 +40f5623ayR1vnzfF__htza35a8Ft-g linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_time.h
    1.68 +40f5623a4YdRdVzYWJzOOoqe8mnrXA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_timer.h
    1.69 +40f5623aDLxmbOtUHvkWztKjAO4EjA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h
    1.70 +40f5623aDMCsWOFO0jktZ4e8sjwvEg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
    1.71 +40f5623arsFXkGdPvIqvFi3yFXGR0Q linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h
    1.72 +40f5623aFTyFTR-vdiA-KaGxk5JOKQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/msr.h
    1.73 +40f5623adgjZq9nAgCt0IXdWl7udSA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/page.h
    1.74 +40f5623a54NuG-7qHihGYmw4wWQnMA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/param.h
    1.75 +40f5623atCokYc2uCysSJ8jFO8TEsw linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgalloc.h
    1.76 +40f5623aEToIXouJgO-ao5d5pcEt1w linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h
    1.77 +40f5623aCCXRPlGpNthVXstGz9ZV3A linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h
    1.78 +40f5623aPCkQQfPtJSooGdhcatrvnQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/processor.h
    1.79 +40f5623bvhcUmESJrtcII6Bmd61b3w linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/ptrace.h
    1.80 +40f5623bzLvxr7WoJIxVf2OH4rCBJg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/segment.h
    1.81 +40f5623bG_LzgG6-qwk292nTc5Wabw linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/setup.h
    1.82 +40f5623bgzm_9vwxpzJswlAxg298Gg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h
    1.83 +40f5623bVdKP7Dt7qm8twu3NcnGNbA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/system.h
    1.84 +40f5623bSgGrvrGRpD71K-lIYqaGgg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/timer.h
    1.85 +40f5623bc8LKPRO09wY5dGDnY_YCpw linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/tlbflush.h
    1.86 +40f5623bxUbeGjkRrjDguCy_Gm8RLw linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/xor.h
    1.87 +40f5623bqoi4GEoBiiUc6TZk1HjsMg linux-2.6.7-xen-sparse/include/asm-xen/blkif.h
    1.88 +40f5623bYNP7tHE2zX6YQxp9Zq2utQ linux-2.6.7-xen-sparse/include/asm-xen/ctrl_if.h
    1.89 +40f5623bDU2mp4xcHrO0ThodQ9Vs7w linux-2.6.7-xen-sparse/include/asm-xen/domain_controller.h
    1.90 +40f5623b3Eqs8pAc5WpPX8_jTzV2qw linux-2.6.7-xen-sparse/include/asm-xen/evtchn.h
    1.91 +40f5623bSHoOzh_pYP9ovjpUz019Aw linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/arch-x86_32.h
    1.92 +40f5623c1uIAB_OVr5AFdoOac7zxHA linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/arch-x86_64.h
    1.93 +40f5623cEbvTM2QIJ8G6kJoYMLvFpw linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/dom0_ops.h
    1.94 +40f5623cBiv7JBB2bwezpyMwyDGN_w linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/event_channel.h
    1.95 +40f5623cvr4j1BQI1I82_K5wRocUKg linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/hypervisor-if.h
    1.96 +40f5623cfHK4EBsPz922OqMVkZX6OA linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/physdev.h
    1.97 +40f5623cFINsV23lGJNQNbhO5kus_Q linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/sched_ctl.h
    1.98 +40f5623cb_pJrLt3h_nAzvJsjsV0rQ linux-2.6.7-xen-sparse/include/asm-xen/hypervisor-ifs/trace.h
    1.99 +40f5623cndVUFlkxpf7Lfx7xu8madQ linux-2.6.7-xen-sparse/include/asm-xen/multicall.h
   1.100 +40f5623cTZ80EwjWUBlh44A9F9i_Lg linux-2.6.7-xen-sparse/include/asm-xen/netif.h
   1.101 +40f5623cBiQhPHILVLrl3xa6bDBaRg linux-2.6.7-xen-sparse/include/asm-xen/xen.h
   1.102  40e1b09db5mN69Ijj0X_Eol-S7dXiw tools/Make.defs
   1.103  3f776bd1Hy9rn69ntXBhPReUFw9IEA tools/Makefile
   1.104  401d7e160vaxMBAUSLSicuZ7AQjJ3w tools/examples/Makefile
     2.1 --- a/BitKeeper/etc/ignore	Wed Jul 14 15:26:41 2004 +0000
     2.2 +++ b/BitKeeper/etc/ignore	Wed Jul 14 16:41:41 2004 +0000
     2.3 @@ -13,8 +13,8 @@ TAGS
     2.4  extras/mini-os/h/hypervisor-ifs
     2.5  install
     2.6  install/*
     2.7 -linux-*-xen*/*
     2.8 -linux-2.4.26-xen/*
     2.9 +linux-*-xen0/*
    2.10 +linux-*-xenU/*
    2.11  linux-xen-sparse
    2.12  patches/*
    2.13  tools/*/build/lib*/*.py
     3.1 --- a/BitKeeper/etc/logging_ok	Wed Jul 14 15:26:41 2004 +0000
     3.2 +++ b/BitKeeper/etc/logging_ok	Wed Jul 14 16:41:41 2004 +0000
     3.3 @@ -9,6 +9,7 @@ bd240@labyrinth.cl.cam.ac.uk
     3.4  br260@br260.wolfson.cam.ac.uk
     3.5  br260@labyrinth.cl.cam.ac.uk
     3.6  br260@laudney.cl.cam.ac.uk
     3.7 +cl349@freefall.cl.cam.ac.uk
     3.8  djm@kirby.fc.hp.com
     3.9  gm281@boulderdash.cl.cam.ac.uk
    3.10  iap10@freefall.cl.cam.ac.uk
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/Kconfig	Wed Jul 14 16:41:41 2004 +0000
     4.3 @@ -0,0 +1,67 @@
     4.4 +#
     4.5 +# For a description of the syntax of this configuration file,
     4.6 +# see Documentation/kbuild/kconfig-language.txt.
     4.7 +#
     4.8 +
     4.9 +mainmenu "Linux Kernel Configuration"
    4.10 +
    4.11 +config XEN
    4.12 +	bool
    4.13 +	default y
    4.14 +	help
    4.15 +	  This is the Linux Xen port.
    4.16 +
    4.17 +config ARCH_XEN
    4.18 +	bool
    4.19 +	default y
    4.20 +
    4.21 +
    4.22 +source "init/Kconfig"
    4.23 +
    4.24 +#config VT
    4.25 +#	bool
    4.26 +#	default y
    4.27 +
    4.28 +#config VT_CONSOLE
    4.29 +#	bool
    4.30 +#	default y
    4.31 +
    4.32 +#config HW_CONSOLE
    4.33 +#	bool
    4.34 +#	default y
    4.35 +
    4.36 +choice
    4.37 +	prompt "Processor Type"
    4.38 +	default X86
    4.39 +
    4.40 +config X86
    4.41 +	bool "X86"
    4.42 +	help
    4.43 +	  Choose this option if your computer is a X86 architecture.
    4.44 +
    4.45 +config X86_64
    4.46 +	bool "X86_64"
    4.47 +	help
    4.48 +	  Choose this option if your computer is a X86 architecture.
    4.49 +
    4.50 +endchoice
    4.51 +
    4.52 +if X86
    4.53 +source "arch/xen/i386/Kconfig"
    4.54 +endif
    4.55 +
    4.56 +menu "Executable file formats"
    4.57 +
    4.58 +source "fs/Kconfig.binfmt"
    4.59 +
    4.60 +endmenu
    4.61 +
    4.62 +source "arch/xen/Kconfig.drivers"
    4.63 +
    4.64 +source "fs/Kconfig"
    4.65 +
    4.66 +source "security/Kconfig"
    4.67 +
    4.68 +source "crypto/Kconfig"
    4.69 +
    4.70 +source "lib/Kconfig"
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/Kconfig.drivers	Wed Jul 14 16:41:41 2004 +0000
     5.3 @@ -0,0 +1,71 @@
     5.4 +# arch/xen/Kconfig.drivers
     5.5 +
     5.6 +menu "Device Drivers"
     5.7 +
     5.8 +source "drivers/base/Kconfig"
     5.9 +
    5.10 +#source "drivers/block/Kconfig"
    5.11 +
    5.12 +source "net/Kconfig"
    5.13 +
    5.14 +#source "drivers/input/Kconfig"
    5.15 +
    5.16 +config INPUT
    5.17 +	tristate "Input devices (needed for keyboard, mouse, ...)" if EMBEDDED
    5.18 +	default y
    5.19 +	---help---
    5.20 +	  Say Y here if you have any input device (mouse, keyboard, tablet,
    5.21 +	  joystick, steering wheel ...) connected to your system and want
    5.22 +	  it to be available to applications. This includes standard PS/2
    5.23 +	  keyboard and mouse.
    5.24 +
    5.25 +	  Say N here if you have a headless (no monitor, no keyboard) system.
    5.26 +
    5.27 +	  More information is available: <file:Documentation/input/input.txt>
    5.28 +
    5.29 +	  If unsure, say Y.
    5.30 +
    5.31 +	  To compile this driver as a module, choose M here: the
    5.32 +	  module will be called input.
    5.33 +
    5.34 +#source "drivers/char/Kconfig"
    5.35 +
    5.36 +config UNIX98_PTYS
    5.37 +	bool "Unix98 PTY support" if EMBEDDED
    5.38 +	default y
    5.39 +	---help---
    5.40 +	  A pseudo terminal (PTY) is a software device consisting of two
    5.41 +	  halves: a master and a slave. The slave device behaves identical to
    5.42 +	  a physical terminal; the master device is used by a process to
    5.43 +	  read data from and write data to the slave, thereby emulating a
    5.44 +	  terminal. Typical programs for the master side are telnet servers
    5.45 +	  and xterms.
    5.46 +
    5.47 +	  Linux has traditionally used the BSD-like names /dev/ptyxx for
    5.48 +	  masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
    5.49 +	  has a number of problems. The GNU C library glibc 2.1 and later,
    5.50 +	  however, supports the Unix98 naming standard: in order to acquire a
    5.51 +	  pseudo terminal, a process opens /dev/ptmx; the number of the pseudo
    5.52 +	  terminal is then made available to the process and the pseudo
    5.53 +	  terminal slave can be accessed as /dev/pts/<number>. What was
    5.54 +	  traditionally /dev/ttyp2 will then be /dev/pts/2, for example.
    5.55 +
    5.56 +	  All modern Linux systems use the Unix98 ptys.  Say Y unless
    5.57 +	  you're on an embedded system and want to conserve memory.
    5.58 +
    5.59 +
    5.60 +#source "drivers/video/Kconfig"
    5.61 +
    5.62 +#config XEN_EVTCHN
    5.63 +#	bool "Xen Event Channel"
    5.64 +#	depends on XEN
    5.65 +#	default Y
    5.66 +#
    5.67 +#config XEN_CONSOLE
    5.68 +#	bool "Xen Console"
    5.69 +#	depends on XEN && XEN_EVTCHN
    5.70 +#	default Y
    5.71 +#	help
    5.72 +#	  Say Y to build a console driver for Xen.
    5.73 +
    5.74 +endmenu
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/Makefile	Wed Jul 14 16:41:41 2004 +0000
     6.3 @@ -0,0 +1,65 @@
     6.4 +#
     6.5 +# xen/Makefile
     6.6 +#
     6.7 +# This file is included by the global makefile so that you can add your own
     6.8 +# architecture-specific flags and dependencies. Remember to do have actions
     6.9 +# for "archclean" cleaning up for this architecture.
    6.10 +#
    6.11 +# This file is subject to the terms and conditions of the GNU General Public
    6.12 +# License.  See the file "COPYING" in the main directory of this archive
    6.13 +# for more details.
    6.14 +#
    6.15 +# Copyright (C) 2004 by Christian Limpach
    6.16 +#
    6.17 +
    6.18 +XENARCH	:= $(subst ",,$(CONFIG_XENARCH))
    6.19 +
    6.20 +# pick up headers from include/asm-xen/asm in preference over include/asm
    6.21 +NOSTDINC_FLAGS  = -nostdinc -iwithprefix include/asm-xen -Iinclude/asm-xen -iwithprefix include
    6.22 +
    6.23 +# make uname return the processor arch
    6.24 +UTS_MACHINE := $(XENARCH)
    6.25 +
    6.26 +core-y	+= arch/xen/kernel/
    6.27 +
    6.28 +drivers-y	+= drivers/xen/
    6.29 +
    6.30 +include/.asm-ignore:
    6.31 +	@rm -f include/.asm-ignore
    6.32 +	@mv include/asm include/.asm-ignore
    6.33 +	@echo '  SYMLINK include/asm -> include/asm-$(XENARCH)'
    6.34 +	$(Q)if [ ! -d include ]; then mkdir -p include; fi;
    6.35 +	@ln -fsn asm-$(XENARCH) include/asm
    6.36 +
    6.37 +include/asm-xen/asm:
    6.38 +	@echo '  SYMLINK $@ -> include/asm-xen/asm-$(XENARCH)'
    6.39 +	@ln -fsn asm-$(XENARCH) $@
    6.40 +
    6.41 +include/asm-xen/asm-$(XENARCH)/hypervisor-ifs:
    6.42 +	@echo '  SYMLINK $@ -> include/asm-xen/hypervisor-ifs'
    6.43 +	@ln -fsn ../hypervisor-ifs $@
    6.44 +
    6.45 +arch/xen/arch:
    6.46 +	@rm -f $@
    6.47 +	@ln -fsn $(XENARCH) $@
    6.48 +
    6.49 +prepare: include/.asm-ignore include/asm-xen/asm \
    6.50 +	include/asm-xen/asm-$(XENARCH)/hypervisor-ifs \
    6.51 +	arch/xen/arch ;
    6.52 +
    6.53 +all: vmlinuz
    6.54 +
    6.55 +vmlinuz: vmlinux
    6.56 +	$(Q)$(MAKE) $(build)=arch/xen/boot vmlinuz
    6.57 +
    6.58 +archclean:
    6.59 +	@if [ -e arch/xen/arch ]; then $(MAKE) $(clean)=arch/xen/arch; fi;
    6.60 +	@rm -f arch/xen/arch include/.asm-ignore include/asm-xen/asm
    6.61 +
    6.62 +define archhelp
    6.63 +  echo  '* vmlinuz	- Compressed kernel image'
    6.64 +endef
    6.65 +
    6.66 +ifneq ($(XENARCH),)
    6.67 +include	$(srctree)/arch/xen/$(XENARCH)/Makefile
    6.68 +endif
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/boot/Makefile	Wed Jul 14 16:41:41 2004 +0000
     7.3 @@ -0,0 +1,3 @@
     7.4 +
     7.5 +vmlinuz: vmlinux FORCE
     7.6 +	$(call if_changed,gzip)
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/defconfig	Wed Jul 14 16:41:41 2004 +0000
     8.3 @@ -0,0 +1,373 @@
     8.4 +#
     8.5 +# Automatically generated make config: don't edit
     8.6 +#
     8.7 +CONFIG_XEN=y
     8.8 +CONFIG_ARCH_XEN=y
     8.9 +
    8.10 +#
    8.11 +# Code maturity level options
    8.12 +#
    8.13 +CONFIG_EXPERIMENTAL=y
    8.14 +CONFIG_CLEAN_COMPILE=y
    8.15 +CONFIG_STANDALONE=y
    8.16 +CONFIG_BROKEN_ON_SMP=y
    8.17 +
    8.18 +#
    8.19 +# General setup
    8.20 +#
    8.21 +CONFIG_SWAP=y
    8.22 +CONFIG_SYSVIPC=y
    8.23 +# CONFIG_POSIX_MQUEUE is not set
    8.24 +# CONFIG_BSD_PROCESS_ACCT is not set
    8.25 +CONFIG_SYSCTL=y
    8.26 +# CONFIG_AUDIT is not set
    8.27 +CONFIG_LOG_BUF_SHIFT=14
    8.28 +# CONFIG_HOTPLUG is not set
    8.29 +# CONFIG_IKCONFIG is not set
    8.30 +# CONFIG_EMBEDDED is not set
    8.31 +CONFIG_KALLSYMS=y
    8.32 +CONFIG_FUTEX=y
    8.33 +CONFIG_EPOLL=y
    8.34 +CONFIG_IOSCHED_NOOP=y
    8.35 +CONFIG_IOSCHED_AS=y
    8.36 +CONFIG_IOSCHED_DEADLINE=y
    8.37 +CONFIG_IOSCHED_CFQ=y
    8.38 +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
    8.39 +
    8.40 +#
    8.41 +# Loadable module support
    8.42 +#
    8.43 +# CONFIG_MODULES is not set
    8.44 +CONFIG_X86=y
    8.45 +# CONFIG_X86_64 is not set
    8.46 +
    8.47 +#
    8.48 +# X86 Processor Configuration
    8.49 +#
    8.50 +CONFIG_XENARCH="i386"
    8.51 +CONFIG_MMU=y
    8.52 +CONFIG_UID16=y
    8.53 +CONFIG_GENERIC_ISA_DMA=y
    8.54 +# CONFIG_M386 is not set
    8.55 +# CONFIG_M486 is not set
    8.56 +# CONFIG_M586 is not set
    8.57 +# CONFIG_M586TSC is not set
    8.58 +# CONFIG_M586MMX is not set
    8.59 +# CONFIG_M686 is not set
    8.60 +# CONFIG_MPENTIUMII is not set
    8.61 +# CONFIG_MPENTIUMIII is not set
    8.62 +# CONFIG_MPENTIUMM is not set
    8.63 +CONFIG_MPENTIUM4=y
    8.64 +# CONFIG_MK6 is not set
    8.65 +# CONFIG_MK7 is not set
    8.66 +# CONFIG_MK8 is not set
    8.67 +# CONFIG_MCRUSOE is not set
    8.68 +# CONFIG_MWINCHIPC6 is not set
    8.69 +# CONFIG_MWINCHIP2 is not set
    8.70 +# CONFIG_MWINCHIP3D is not set
    8.71 +# CONFIG_MCYRIXIII is not set
    8.72 +# CONFIG_MVIAC3_2 is not set
    8.73 +# CONFIG_X86_GENERIC is not set
    8.74 +CONFIG_X86_CMPXCHG=y
    8.75 +CONFIG_X86_XADD=y
    8.76 +CONFIG_X86_L1_CACHE_SHIFT=7
    8.77 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
    8.78 +CONFIG_X86_WP_WORKS_OK=y
    8.79 +CONFIG_X86_INVLPG=y
    8.80 +CONFIG_X86_BSWAP=y
    8.81 +CONFIG_X86_POPAD_OK=y
    8.82 +CONFIG_X86_GOOD_APIC=y
    8.83 +CONFIG_X86_INTEL_USERCOPY=y
    8.84 +CONFIG_X86_USE_PPRO_CHECKSUM=y
    8.85 +# CONFIG_HPET_TIMER is not set
    8.86 +# CONFIG_HPET_EMULATE_RTC is not set
    8.87 +# CONFIG_SMP is not set
    8.88 +CONFIG_PREEMPT=y
    8.89 +CONFIG_X86_CPUID=y
    8.90 +
    8.91 +#
    8.92 +# Firmware Drivers
    8.93 +#
    8.94 +# CONFIG_EDD is not set
    8.95 +CONFIG_NOHIGHMEM=y
    8.96 +# CONFIG_HIGHMEM4G is not set
    8.97 +# CONFIG_HIGHMEM64G is not set
    8.98 +CONFIG_HAVE_DEC_LOCK=y
    8.99 +# CONFIG_REGPARM is not set
   8.100 +
   8.101 +#
   8.102 +# Kernel hacking
   8.103 +#
   8.104 +# CONFIG_DEBUG_KERNEL is not set
   8.105 +CONFIG_EARLY_PRINTK=y
   8.106 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
   8.107 +# CONFIG_FRAME_POINTER is not set
   8.108 +# CONFIG_4KSTACKS is not set
   8.109 +CONFIG_X86_BIOS_REBOOT=y
   8.110 +CONFIG_X86_STD_RESOURCES=y
   8.111 +CONFIG_PC=y
   8.112 +
   8.113 +#
   8.114 +# Executable file formats
   8.115 +#
   8.116 +CONFIG_BINFMT_ELF=y
   8.117 +# CONFIG_BINFMT_AOUT is not set
   8.118 +# CONFIG_BINFMT_MISC is not set
   8.119 +
   8.120 +#
   8.121 +# Device Drivers
   8.122 +#
   8.123 +
   8.124 +#
   8.125 +# Generic Driver Options
   8.126 +#
   8.127 +
   8.128 +#
   8.129 +# Networking support
   8.130 +#
   8.131 +CONFIG_NET=y
   8.132 +
   8.133 +#
   8.134 +# Networking options
   8.135 +#
   8.136 +CONFIG_PACKET=y
   8.137 +# CONFIG_PACKET_MMAP is not set
   8.138 +# CONFIG_NETLINK_DEV is not set
   8.139 +CONFIG_UNIX=y
   8.140 +# CONFIG_NET_KEY is not set
   8.141 +CONFIG_INET=y
   8.142 +# CONFIG_IP_MULTICAST is not set
   8.143 +# CONFIG_IP_ADVANCED_ROUTER is not set
   8.144 +CONFIG_IP_PNP=y
   8.145 +# CONFIG_IP_PNP_DHCP is not set
   8.146 +# CONFIG_IP_PNP_BOOTP is not set
   8.147 +# CONFIG_IP_PNP_RARP is not set
   8.148 +# CONFIG_NET_IPIP is not set
   8.149 +# CONFIG_NET_IPGRE is not set
   8.150 +# CONFIG_ARPD is not set
   8.151 +# CONFIG_SYN_COOKIES is not set
   8.152 +# CONFIG_INET_AH is not set
   8.153 +# CONFIG_INET_ESP is not set
   8.154 +# CONFIG_INET_IPCOMP is not set
   8.155 +# CONFIG_IPV6 is not set
   8.156 +# CONFIG_NETFILTER is not set
   8.157 +
   8.158 +#
   8.159 +# SCTP Configuration (EXPERIMENTAL)
   8.160 +#
   8.161 +# CONFIG_IP_SCTP is not set
   8.162 +# CONFIG_ATM is not set
   8.163 +# CONFIG_BRIDGE is not set
   8.164 +# CONFIG_VLAN_8021Q is not set
   8.165 +# CONFIG_DECNET is not set
   8.166 +# CONFIG_LLC2 is not set
   8.167 +# CONFIG_IPX is not set
   8.168 +# CONFIG_ATALK is not set
   8.169 +# CONFIG_X25 is not set
   8.170 +# CONFIG_LAPB is not set
   8.171 +# CONFIG_NET_DIVERT is not set
   8.172 +# CONFIG_ECONET is not set
   8.173 +# CONFIG_WAN_ROUTER is not set
   8.174 +# CONFIG_NET_FASTROUTE is not set
   8.175 +# CONFIG_NET_HW_FLOWCONTROL is not set
   8.176 +
   8.177 +#
   8.178 +# QoS and/or fair queueing
   8.179 +#
   8.180 +# CONFIG_NET_SCHED is not set
   8.181 +
   8.182 +#
   8.183 +# Network testing
   8.184 +#
   8.185 +# CONFIG_NET_PKTGEN is not set
   8.186 +# CONFIG_NETPOLL is not set
   8.187 +# CONFIG_NET_POLL_CONTROLLER is not set
   8.188 +# CONFIG_HAMRADIO is not set
   8.189 +# CONFIG_IRDA is not set
   8.190 +# CONFIG_BT is not set
   8.191 +CONFIG_NETDEVICES=y
   8.192 +# CONFIG_DUMMY is not set
   8.193 +# CONFIG_BONDING is not set
   8.194 +# CONFIG_EQUALIZER is not set
   8.195 +# CONFIG_TUN is not set
   8.196 +
   8.197 +#
   8.198 +# Ethernet (10 or 100Mbit)
   8.199 +#
   8.200 +# CONFIG_NET_ETHERNET is not set
   8.201 +
   8.202 +#
   8.203 +# Ethernet (1000 Mbit)
   8.204 +#
   8.205 +
   8.206 +#
   8.207 +# Ethernet (10000 Mbit)
   8.208 +#
   8.209 +
   8.210 +#
   8.211 +# Token Ring devices
   8.212 +#
   8.213 +
   8.214 +#
   8.215 +# Wireless LAN (non-hamradio)
   8.216 +#
   8.217 +# CONFIG_NET_RADIO is not set
   8.218 +
   8.219 +#
   8.220 +# Wan interfaces
   8.221 +#
   8.222 +# CONFIG_WAN is not set
   8.223 +# CONFIG_PPP is not set
   8.224 +# CONFIG_SLIP is not set
   8.225 +# CONFIG_SHAPER is not set
   8.226 +# CONFIG_NETCONSOLE is not set
   8.227 +CONFIG_INPUT=y
   8.228 +CONFIG_UNIX98_PTYS=y
   8.229 +
   8.230 +#
   8.231 +# File systems
   8.232 +#
   8.233 +CONFIG_EXT2_FS=y
   8.234 +# CONFIG_EXT2_FS_XATTR is not set
   8.235 +CONFIG_EXT3_FS=y
   8.236 +CONFIG_EXT3_FS_XATTR=y
   8.237 +# CONFIG_EXT3_FS_POSIX_ACL is not set
   8.238 +# CONFIG_EXT3_FS_SECURITY is not set
   8.239 +CONFIG_JBD=y
   8.240 +# CONFIG_JBD_DEBUG is not set
   8.241 +CONFIG_FS_MBCACHE=y
   8.242 +# CONFIG_REISERFS_FS is not set
   8.243 +# CONFIG_JFS_FS is not set
   8.244 +# CONFIG_XFS_FS is not set
   8.245 +# CONFIG_MINIX_FS is not set
   8.246 +# CONFIG_ROMFS_FS is not set
   8.247 +# CONFIG_QUOTA is not set
   8.248 +# CONFIG_AUTOFS_FS is not set
   8.249 +# CONFIG_AUTOFS4_FS is not set
   8.250 +
   8.251 +#
   8.252 +# CD-ROM/DVD Filesystems
   8.253 +#
   8.254 +# CONFIG_ISO9660_FS is not set
   8.255 +# CONFIG_UDF_FS is not set
   8.256 +
   8.257 +#
   8.258 +# DOS/FAT/NT Filesystems
   8.259 +#
   8.260 +# CONFIG_FAT_FS is not set
   8.261 +# CONFIG_NTFS_FS is not set
   8.262 +
   8.263 +#
   8.264 +# Pseudo filesystems
   8.265 +#
   8.266 +CONFIG_PROC_FS=y
   8.267 +CONFIG_PROC_KCORE=y
   8.268 +CONFIG_SYSFS=y
   8.269 +# CONFIG_DEVFS_FS is not set
   8.270 +# CONFIG_DEVPTS_FS_XATTR is not set
   8.271 +CONFIG_TMPFS=y
   8.272 +# CONFIG_HUGETLBFS is not set
   8.273 +# CONFIG_HUGETLB_PAGE is not set
   8.274 +CONFIG_RAMFS=y
   8.275 +
   8.276 +#
   8.277 +# Miscellaneous filesystems
   8.278 +#
   8.279 +# CONFIG_ADFS_FS is not set
   8.280 +# CONFIG_AFFS_FS is not set
   8.281 +# CONFIG_HFS_FS is not set
   8.282 +# CONFIG_HFSPLUS_FS is not set
   8.283 +# CONFIG_BEFS_FS is not set
   8.284 +# CONFIG_BFS_FS is not set
   8.285 +# CONFIG_EFS_FS is not set
   8.286 +# CONFIG_CRAMFS is not set
   8.287 +# CONFIG_VXFS_FS is not set
   8.288 +# CONFIG_HPFS_FS is not set
   8.289 +# CONFIG_QNX4FS_FS is not set
   8.290 +# CONFIG_SYSV_FS is not set
   8.291 +# CONFIG_UFS_FS is not set
   8.292 +
   8.293 +#
   8.294 +# Network File Systems
   8.295 +#
   8.296 +CONFIG_NFS_FS=y
   8.297 +CONFIG_NFS_V3=y
   8.298 +# CONFIG_NFS_V4 is not set
   8.299 +# CONFIG_NFS_DIRECTIO is not set
   8.300 +# CONFIG_NFSD is not set
   8.301 +CONFIG_ROOT_NFS=y
   8.302 +CONFIG_LOCKD=y
   8.303 +CONFIG_LOCKD_V4=y
   8.304 +# CONFIG_EXPORTFS is not set
   8.305 +CONFIG_SUNRPC=y
   8.306 +# CONFIG_RPCSEC_GSS_KRB5 is not set
   8.307 +# CONFIG_SMB_FS is not set
   8.308 +# CONFIG_CIFS is not set
   8.309 +# CONFIG_NCP_FS is not set
   8.310 +# CONFIG_CODA_FS is not set
   8.311 +# CONFIG_AFS_FS is not set
   8.312 +
   8.313 +#
   8.314 +# Partition Types
   8.315 +#
   8.316 +# CONFIG_PARTITION_ADVANCED is not set
   8.317 +CONFIG_MSDOS_PARTITION=y
   8.318 +
   8.319 +#
   8.320 +# Native Language Support
   8.321 +#
   8.322 +CONFIG_NLS=y
   8.323 +CONFIG_NLS_DEFAULT="iso8859-1"
   8.324 +CONFIG_NLS_CODEPAGE_437=y
   8.325 +# CONFIG_NLS_CODEPAGE_737 is not set
   8.326 +# CONFIG_NLS_CODEPAGE_775 is not set
   8.327 +# CONFIG_NLS_CODEPAGE_850 is not set
   8.328 +# CONFIG_NLS_CODEPAGE_852 is not set
   8.329 +# CONFIG_NLS_CODEPAGE_855 is not set
   8.330 +# CONFIG_NLS_CODEPAGE_857 is not set
   8.331 +# CONFIG_NLS_CODEPAGE_860 is not set
   8.332 +# CONFIG_NLS_CODEPAGE_861 is not set
   8.333 +# CONFIG_NLS_CODEPAGE_862 is not set
   8.334 +# CONFIG_NLS_CODEPAGE_863 is not set
   8.335 +# CONFIG_NLS_CODEPAGE_864 is not set
   8.336 +# CONFIG_NLS_CODEPAGE_865 is not set
   8.337 +# CONFIG_NLS_CODEPAGE_866 is not set
   8.338 +# CONFIG_NLS_CODEPAGE_869 is not set
   8.339 +# CONFIG_NLS_CODEPAGE_936 is not set
   8.340 +# CONFIG_NLS_CODEPAGE_950 is not set
   8.341 +# CONFIG_NLS_CODEPAGE_932 is not set
   8.342 +# CONFIG_NLS_CODEPAGE_949 is not set
   8.343 +# CONFIG_NLS_CODEPAGE_874 is not set
   8.344 +# CONFIG_NLS_ISO8859_8 is not set
   8.345 +# CONFIG_NLS_CODEPAGE_1250 is not set
   8.346 +# CONFIG_NLS_CODEPAGE_1251 is not set
   8.347 +CONFIG_NLS_ISO8859_1=y
   8.348 +# CONFIG_NLS_ISO8859_2 is not set
   8.349 +# CONFIG_NLS_ISO8859_3 is not set
   8.350 +# CONFIG_NLS_ISO8859_4 is not set
   8.351 +# CONFIG_NLS_ISO8859_5 is not set
   8.352 +# CONFIG_NLS_ISO8859_6 is not set
   8.353 +# CONFIG_NLS_ISO8859_7 is not set
   8.354 +# CONFIG_NLS_ISO8859_9 is not set
   8.355 +# CONFIG_NLS_ISO8859_13 is not set
   8.356 +# CONFIG_NLS_ISO8859_14 is not set
   8.357 +# CONFIG_NLS_ISO8859_15 is not set
   8.358 +# CONFIG_NLS_KOI8_R is not set
   8.359 +# CONFIG_NLS_KOI8_U is not set
   8.360 +# CONFIG_NLS_UTF8 is not set
   8.361 +
   8.362 +#
   8.363 +# Security options
   8.364 +#
   8.365 +# CONFIG_SECURITY is not set
   8.366 +
   8.367 +#
   8.368 +# Cryptographic options
   8.369 +#
   8.370 +# CONFIG_CRYPTO is not set
   8.371 +
   8.372 +#
   8.373 +# Library routines
   8.374 +#
   8.375 +CONFIG_CRC32=y
   8.376 +CONFIG_LIBCRC32C=y
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/Kconfig	Wed Jul 14 16:41:41 2004 +0000
     9.3 @@ -0,0 +1,784 @@
     9.4 +#
     9.5 +# For a description of the syntax of this configuration file,
     9.6 +# see Documentation/kbuild/kconfig-language.txt.
     9.7 +#
     9.8 +
     9.9 +menu "X86 Processor Configuration"
    9.10 +
    9.11 +config XENARCH
    9.12 +	string
    9.13 +	default i386
    9.14 +
    9.15 +config MMU
    9.16 +	bool
    9.17 +	default y
    9.18 +
    9.19 +config SBUS
    9.20 +	bool
    9.21 +
    9.22 +config UID16
    9.23 +	bool
    9.24 +	default y
    9.25 +
    9.26 +config GENERIC_ISA_DMA
    9.27 +	bool
    9.28 +	default y
    9.29 +
    9.30 +
    9.31 +choice
    9.32 +	prompt "Processor family"
    9.33 +	default M686
    9.34 +
    9.35 +config M386
    9.36 +	bool "386"
    9.37 +	---help---
    9.38 +	  This is the processor type of your CPU. This information is used for
    9.39 +	  optimizing purposes. In order to compile a kernel that can run on
    9.40 +	  all x86 CPU types (albeit not optimally fast), you can specify
    9.41 +	  "386" here.
    9.42 +
    9.43 +	  The kernel will not necessarily run on earlier architectures than
    9.44 +	  the one you have chosen, e.g. a Pentium optimized kernel will run on
    9.45 +	  a PPro, but not necessarily on a i486.
    9.46 +
    9.47 +	  Here are the settings recommended for greatest speed:
    9.48 +	  - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
    9.49 +	  486DLC/DLC2, UMC 486SX-S and NexGen Nx586.  Only "386" kernels
    9.50 +	  will run on a 386 class machine.
    9.51 +	  - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
    9.52 +	  SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
    9.53 +	  - "586" for generic Pentium CPUs lacking the TSC
    9.54 +	  (time stamp counter) register.
    9.55 +	  - "Pentium-Classic" for the Intel Pentium.
    9.56 +	  - "Pentium-MMX" for the Intel Pentium MMX.
    9.57 +	  - "Pentium-Pro" for the Intel Pentium Pro.
    9.58 +	  - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
    9.59 +	  - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
    9.60 +	  - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
    9.61 +	  - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
    9.62 +	  - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
    9.63 +	  - "Crusoe" for the Transmeta Crusoe series.
    9.64 +	  - "Winchip-C6" for original IDT Winchip.
    9.65 +	  - "Winchip-2" for IDT Winchip 2.
    9.66 +	  - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
    9.67 +	  - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
    9.68 +	  - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
    9.69 +
    9.70 +	  If you don't know what to do, choose "386".
    9.71 +
    9.72 +config M486
    9.73 +	bool "486"
    9.74 +	help
    9.75 +	  Select this for a 486 series processor, either Intel or one of the
    9.76 +	  compatible processors from AMD, Cyrix, IBM, or Intel.  Includes DX,
    9.77 +	  DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
    9.78 +	  U5S.
    9.79 +
    9.80 +config M586
    9.81 +	bool "586/K5/5x86/6x86/6x86MX"
    9.82 +	help
    9.83 +	  Select this for an 586 or 686 series processor such as the AMD K5,
    9.84 +	  the Intel 5x86 or 6x86, or the Intel 6x86MX.  This choice does not
    9.85 +	  assume the RDTSC (Read Time Stamp Counter) instruction.
    9.86 +
    9.87 +config M586TSC
    9.88 +	bool "Pentium-Classic"
    9.89 +	help
    9.90 +	  Select this for a Pentium Classic processor with the RDTSC (Read
    9.91 +	  Time Stamp Counter) instruction for benchmarking.
    9.92 +
    9.93 +config M586MMX
    9.94 +	bool "Pentium-MMX"
    9.95 +	help
    9.96 +	  Select this for a Pentium with the MMX graphics/multimedia
    9.97 +	  extended instructions.
    9.98 +
    9.99 +config M686
   9.100 +	bool "Pentium-Pro"
   9.101 +	help
   9.102 +	  Select this for Intel Pentium Pro chips.  This enables the use of
   9.103 +	  Pentium Pro extended instructions, and disables the init-time guard
   9.104 +	  against the f00f bug found in earlier Pentiums.
   9.105 +
   9.106 +config MPENTIUMII
   9.107 +	bool "Pentium-II/Celeron(pre-Coppermine)"
   9.108 +	help
   9.109 +	  Select this for Intel chips based on the Pentium-II and
   9.110 +	  pre-Coppermine Celeron core.  This option enables an unaligned
   9.111 +	  copy optimization, compiles the kernel with optimization flags
   9.112 +	  tailored for the chip, and applies any applicable Pentium Pro
   9.113 +	  optimizations.
   9.114 +
   9.115 +config MPENTIUMIII
   9.116 +	bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
   9.117 +	help
   9.118 +	  Select this for Intel chips based on the Pentium-III and
   9.119 +	  Celeron-Coppermine core.  This option enables use of some
   9.120 +	  extended prefetch instructions in addition to the Pentium II
   9.121 +	  extensions.
   9.122 +
   9.123 +config MPENTIUMM
   9.124 +	bool "Pentium M"
   9.125 +	help
   9.126 +	  Select this for Intel Pentium M (not Pentium-4 M)
   9.127 +	  notebook chips.
   9.128 +
   9.129 +config MPENTIUM4
   9.130 +	bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
   9.131 +	help
   9.132 +	  Select this for Intel Pentium 4 chips.  This includes the
   9.133 +	  Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
   9.134 +	  (not Pentium M) chips.  This option enables compile flags
   9.135 +	  optimized for the chip, uses the correct cache shift, and
   9.136 +	  applies any applicable Pentium III optimizations.
   9.137 +
   9.138 +config MK6
   9.139 +	bool "K6/K6-II/K6-III"
   9.140 +	help
   9.141 +	  Select this for an AMD K6-family processor.  Enables use of
   9.142 +	  some extended instructions, and passes appropriate optimization
   9.143 +	  flags to GCC.
   9.144 +
   9.145 +config MK7
   9.146 +	bool "Athlon/Duron/K7"
   9.147 +	help
   9.148 +	  Select this for an AMD Athlon K7-family processor.  Enables use of
   9.149 +	  some extended instructions, and passes appropriate optimization
   9.150 +	  flags to GCC.
   9.151 +
   9.152 +config MK8
   9.153 +	bool "Opteron/Athlon64/Hammer/K8"
   9.154 +	help
   9.155 +	  Select this for an AMD Opteron or Athlon64 Hammer-family processor.  Enables
   9.156 +	  use of some extended instructions, and passes appropriate optimization
   9.157 +	  flags to GCC.
   9.158 +
   9.159 +config MCRUSOE
   9.160 +	bool "Crusoe"
   9.161 +	help
   9.162 +	  Select this for a Transmeta Crusoe processor.  Treats the processor
   9.163 +	  like a 586 with TSC, and sets some GCC optimization flags (like a
   9.164 +	  Pentium Pro with no alignment requirements).
   9.165 +
   9.166 +config MWINCHIPC6
   9.167 +	bool "Winchip-C6"
   9.168 +	help
   9.169 +	  Select this for an IDT Winchip C6 chip.  Linux and GCC
   9.170 +	  treat this chip as a 586TSC with some extended instructions
   9.171 +	  and alignment requirements.
   9.172 +
   9.173 +config MWINCHIP2
   9.174 +	bool "Winchip-2"
   9.175 +	help
   9.176 +	  Select this for an IDT Winchip-2.  Linux and GCC
   9.177 +	  treat this chip as a 586TSC with some extended instructions
   9.178 +	  and alignment requirements.
   9.179 +
   9.180 +config MWINCHIP3D
   9.181 +	bool "Winchip-2A/Winchip-3"
   9.182 +	help
   9.183 +	  Select this for an IDT Winchip-2A or 3.  Linux and GCC
   9.184 +	  treat this chip as a 586TSC with some extended instructions
   9.185 +	  and alignment reqirements.  Also enable out of order memory
   9.186 +	  stores for this CPU, which can increase performance of some
   9.187 +	  operations.
   9.188 +
   9.189 +config MCYRIXIII
   9.190 +	bool "CyrixIII/VIA-C3"
   9.191 +	help
   9.192 +	  Select this for a Cyrix III or C3 chip.  Presently Linux and GCC
   9.193 +	  treat this chip as a generic 586. Whilst the CPU is 686 class,
   9.194 +	  it lacks the cmov extension which gcc assumes is present when
   9.195 +	  generating 686 code.
   9.196 +	  Note that Nehemiah (Model 9) and above will not boot with this
   9.197 +	  kernel due to them lacking the 3DNow! instructions used in earlier
   9.198 +	  incarnations of the CPU.
   9.199 +
   9.200 +config MVIAC3_2
   9.201 +	bool "VIA C3-2 (Nehemiah)"
   9.202 +	help
   9.203 +	  Select this for a VIA C3 "Nehemiah". Selecting this enables usage
   9.204 +	  of SSE and tells gcc to treat the CPU as a 686.
   9.205 +	  Note, this kernel will not boot on older (pre model 9) C3s.
   9.206 +
   9.207 +endchoice
   9.208 +
   9.209 +config X86_GENERIC
   9.210 +       bool "Generic x86 support" 
   9.211 +       help
   9.212 +	  Instead of just including optimizations for the selected
   9.213 +	  x86 variant (e.g. PII, Crusoe or Athlon), include some more
   9.214 +	  generic optimizations as well. This will make the kernel
   9.215 +	  perform better on x86 CPUs other than that selected.
   9.216 +
   9.217 +	  This is really intended for distributors who need more
   9.218 +	  generic optimizations.
   9.219 +
   9.220 +#
   9.221 +# Define implied options from the CPU selection here
   9.222 +#
   9.223 +config X86_CMPXCHG
   9.224 +	bool
   9.225 +	depends on !M386
   9.226 +	default y
   9.227 +
   9.228 +config X86_XADD
   9.229 +	bool
   9.230 +	depends on !M386
   9.231 +	default y
   9.232 +
   9.233 +config X86_L1_CACHE_SHIFT
   9.234 +	int
   9.235 +	default "7" if MPENTIUM4 || X86_GENERIC
   9.236 +	default "4" if X86_ELAN || M486 || M386
   9.237 +	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2
   9.238 +	default "6" if MK7 || MK8 || MPENTIUMM
   9.239 +
   9.240 +config RWSEM_GENERIC_SPINLOCK
   9.241 +	bool
   9.242 +	depends on M386
   9.243 +	default y
   9.244 +
   9.245 +config RWSEM_XCHGADD_ALGORITHM
   9.246 +	bool
   9.247 +	depends on !M386
   9.248 +	default y
   9.249 +
   9.250 +config X86_PPRO_FENCE
   9.251 +	bool
   9.252 +	depends on M686 || M586MMX || M586TSC || M586 || M486 || M386
   9.253 +	default y
   9.254 +
   9.255 +config X86_F00F_BUG
   9.256 +	bool
   9.257 +	depends on M586MMX || M586TSC || M586 || M486 || M386
   9.258 +	default y
   9.259 +
   9.260 +config X86_WP_WORKS_OK
   9.261 +	bool
   9.262 +	depends on !M386
   9.263 +	default y
   9.264 +
   9.265 +config X86_INVLPG
   9.266 +	bool
   9.267 +	depends on !M386
   9.268 +	default y
   9.269 +
   9.270 +config X86_BSWAP
   9.271 +	bool
   9.272 +	depends on !M386
   9.273 +	default y
   9.274 +
   9.275 +config X86_POPAD_OK
   9.276 +	bool
   9.277 +	depends on !M386
   9.278 +	default y
   9.279 +
   9.280 +config X86_ALIGNMENT_16
   9.281 +	bool
   9.282 +	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
   9.283 +	default y
   9.284 +
   9.285 +config X86_GOOD_APIC
   9.286 +	bool
   9.287 +	depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8
   9.288 +	default y
   9.289 +
   9.290 +config X86_INTEL_USERCOPY
   9.291 +	bool
   9.292 +	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7
   9.293 +	default y
   9.294 +
   9.295 +config X86_USE_PPRO_CHECKSUM
   9.296 +	bool
   9.297 +	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2
   9.298 +	default y
   9.299 +
   9.300 +config X86_USE_3DNOW
   9.301 +	bool
   9.302 +	depends on MCYRIXIII || MK7
   9.303 +	default y
   9.304 +
   9.305 +config X86_OOSTORE
   9.306 +	bool
   9.307 +	depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
   9.308 +	default y
   9.309 +
   9.310 +config HPET_TIMER
   9.311 +	bool "HPET Timer Support"
   9.312 +	help
   9.313 +	  This enables the use of the HPET for the kernel's internal timer.
   9.314 +	  HPET is the next generation timer replacing legacy 8254s.
   9.315 +	  You can safely choose Y here.  However, HPET will only be
   9.316 +	  activated if the platform and the BIOS support this feature.
   9.317 +	  Otherwise the 8254 will be used for timing services.
   9.318 +
   9.319 +	  Choose N to continue using the legacy 8254 timer.
   9.320 +
   9.321 +config HPET_EMULATE_RTC
   9.322 +	def_bool HPET_TIMER && RTC=y
   9.323 +
   9.324 +config SMP
   9.325 +	bool "Symmetric multi-processing support"
   9.326 +	---help---
   9.327 +	  This enables support for systems with more than one CPU. If you have
   9.328 +	  a system with only one CPU, like most personal computers, say N. If
   9.329 +	  you have a system with more than one CPU, say Y.
   9.330 +
   9.331 +	  If you say N here, the kernel will run on single and multiprocessor
   9.332 +	  machines, but will use only one CPU of a multiprocessor machine. If
   9.333 +	  you say Y here, the kernel will run on many, but not all,
   9.334 +	  singleprocessor machines. On a singleprocessor machine, the kernel
   9.335 +	  will run faster if you say N here.
   9.336 +
   9.337 +	  Note that if you say Y here and choose architecture "586" or
   9.338 +	  "Pentium" under "Processor family", the kernel will not work on 486
   9.339 +	  architectures. Similarly, multiprocessor kernels for the "PPro"
   9.340 +	  architecture may not work on all Pentium based boards.
   9.341 +
   9.342 +	  People using multiprocessor machines who say Y here should also say
   9.343 +	  Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
   9.344 +	  Management" code will be disabled if you say Y here.
   9.345 +
   9.346 +	  See also the <file:Documentation/smp.txt>,
   9.347 +	  <file:Documentation/i386/IO-APIC.txt>,
   9.348 +	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
   9.349 +	  <http://www.tldp.org/docs.html#howto>.
   9.350 +
   9.351 +	  If you don't know what to do here, say N.
   9.352 +
   9.353 +config NR_CPUS
   9.354 +	int "Maximum number of CPUs (2-255)"
   9.355 +	range 2 255
   9.356 +	depends on SMP
   9.357 +	default "32" if X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000
   9.358 +	default "8"
   9.359 +	help
   9.360 +	  This allows you to specify the maximum number of CPUs which this
   9.361 +	  kernel will support.  The maximum supported value is 255 and the
   9.362 +	  minimum value which makes sense is 2.
   9.363 +
   9.364 +	  This is purely to save memory - each supported CPU adds
   9.365 +	  approximately eight kilobytes to the kernel image.
   9.366 +
   9.367 +config SCHED_SMT
   9.368 +	bool "SMT (Hyperthreading) scheduler support"
   9.369 +	depends on SMP
   9.370 +	default off
   9.371 +	help
   9.372 +	  SMT scheduler support improves the CPU scheduler's decision making
   9.373 +	  when dealing with Intel Pentium 4 chips with HyperThreading at a
   9.374 +	  cost of slightly increased overhead in some places. If unsure say
   9.375 +	  N here.
   9.376 +
   9.377 +config PREEMPT
   9.378 +	bool "Preemptible Kernel"
   9.379 +	help
   9.380 +	  This option reduces the latency of the kernel when reacting to
   9.381 +	  real-time or interactive events by allowing a low priority process to
   9.382 +	  be preempted even if it is in kernel mode executing a system call.
   9.383 +	  This allows applications to run more reliably even when the system is
   9.384 +	  under load.
   9.385 +
   9.386 +	  Say Y here if you are building a kernel for a desktop, embedded
   9.387 +	  or real-time system.  Say N if you are unsure.
   9.388 +
   9.389 +#config X86_TSC
   9.390 +#	 bool
   9.391 +#	depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2) && !X86_NUMAQ
   9.392 +#	 default y
   9.393 +
   9.394 +#config X86_MCE
   9.395 +#	 bool "Machine Check Exception"
   9.396 +#	depends on !X86_VOYAGER
   9.397 +#	 ---help---
   9.398 +#	   Machine Check Exception support allows the processor to notify the
   9.399 +#	   kernel if it detects a problem (e.g. overheating, component failure).
   9.400 +#	   The action the kernel takes depends on the severity of the problem,
   9.401 +#	   ranging from a warning message on the console, to halting the machine.
   9.402 +#	   Your processor must be a Pentium or newer to support this - check the
   9.403 +#	   flags in /proc/cpuinfo for mce.  Note that some older Pentium systems
   9.404 +#	   have a design flaw which leads to false MCE events - hence MCE is
   9.405 +#	   disabled on all P5 processors, unless explicitly enabled with "mce"
   9.406 +#	   as a boot argument.  Similarly, if MCE is built in and creates a
   9.407 +#	   problem on some new non-standard machine, you can boot with "nomce"
   9.408 +#	   to disable it.  MCE support simply ignores non-MCE processors like
   9.409 +#	   the 386 and 486, so nearly everyone can say Y here.
   9.410 +
   9.411 +#config X86_MCE_NONFATAL
   9.412 +#	tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
   9.413 +#	 depends on X86_MCE
   9.414 +#	 help
   9.415 +#	   Enabling this feature starts a timer that triggers every 5 seconds which
   9.416 +#	   will look at the machine check registers to see if anything happened.
   9.417 +#	   Non-fatal problems automatically get corrected (but still logged).
   9.418 +#	   Disable this if you don't want to see these messages.
   9.419 +#	   Seeing the messages this option prints out may be indicative of dying hardware,
   9.420 +#	   or out-of-spec (ie, overclocked) hardware.
   9.421 +#	   This option only does something on certain CPUs.
   9.422 +#	   (AMD Athlon/Duron and Intel Pentium 4)
   9.423 +
   9.424 +#config X86_MCE_P4THERMAL
   9.425 +#	 bool "check for P4 thermal throttling interrupt."
   9.426 +#	 depends on X86_MCE && (X86_UP_APIC || SMP)
   9.427 +#	 help
   9.428 +#	   Enabling this feature will cause a message to be printed when the P4
   9.429 +#	   enters thermal throttling.
   9.430 +
   9.431 +#config MICROCODE
   9.432 +#	 tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
   9.433 +#	 ---help---
   9.434 +#	   If you say Y here and also to "/dev file system support" in the
   9.435 +#	   'File systems' section, you will be able to update the microcode on
   9.436 +#	   Intel processors in the IA32 family, e.g. Pentium Pro, Pentium II,
   9.437 +#	   Pentium III, Pentium 4, Xeon etc.  You will obviously need the
   9.438 +#	   actual microcode binary data itself which is not shipped with the
   9.439 +#	   Linux kernel.
   9.440 +#
   9.441 +#	   For latest news and information on obtaining all the required
   9.442 +#	   ingredients for this driver, check:
   9.443 +#	   <http://www.urbanmyth.org/microcode/>.
   9.444 +#
   9.445 +#	   To compile this driver as a module, choose M here: the
   9.446 +#	   module will be called microcode.
   9.447 +
   9.448 +#config X86_MSR
   9.449 +#	 tristate "/dev/cpu/*/msr - Model-specific register support"
   9.450 +#	 help
   9.451 +#	   This device gives privileged processes access to the x86
   9.452 +#	   Model-Specific Registers (MSRs).  It is a character device with
   9.453 +#	   major 202 and minors 0 to 31 for /dev/cpu/0/msr to /dev/cpu/31/msr.
   9.454 +#	   MSR accesses are directed to a specific CPU on multi-processor
   9.455 +#	   systems.
   9.456 +
   9.457 +config X86_CPUID
   9.458 +	tristate "/dev/cpu/*/cpuid - CPU information support"
   9.459 +	help
   9.460 +	  This device gives processes access to the x86 CPUID instruction to
   9.461 +	  be executed on a specific processor.  It is a character device
   9.462 +	  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
   9.463 +	  /dev/cpu/31/cpuid.
   9.464 +
   9.465 +source "drivers/firmware/Kconfig"
   9.466 +
   9.467 +choice
   9.468 +	prompt "High Memory Support"
   9.469 +	default NOHIGHMEM
   9.470 +
   9.471 +config NOHIGHMEM
   9.472 +	bool "off"
   9.473 +	---help---
   9.474 +	  Linux can use up to 64 Gigabytes of physical memory on x86 systems.
   9.475 +	  However, the address space of 32-bit x86 processors is only 4
   9.476 +	  Gigabytes large. That means that, if you have a large amount of
   9.477 +	  physical memory, not all of it can be "permanently mapped" by the
   9.478 +	  kernel. The physical memory that's not permanently mapped is called
   9.479 +	  "high memory".
   9.480 +
   9.481 +	  If you are compiling a kernel which will never run on a machine with
   9.482 +	  more than 1 Gigabyte total physical RAM, answer "off" here (default
   9.483 +	  choice and suitable for most users). This will result in a "3GB/1GB"
   9.484 +	  split: 3GB are mapped so that each process sees a 3GB virtual memory
   9.485 +	  space and the remaining part of the 4GB virtual memory space is used
   9.486 +	  by the kernel to permanently map as much physical memory as
   9.487 +	  possible.
   9.488 +
   9.489 +	  If the machine has between 1 and 4 Gigabytes physical RAM, then
   9.490 +	  answer "4GB" here.
   9.491 +
   9.492 +	  If more than 4 Gigabytes is used then answer "64GB" here. This
   9.493 +	  selection turns Intel PAE (Physical Address Extension) mode on.
   9.494 +	  PAE implements 3-level paging on IA32 processors. PAE is fully
   9.495 +	  supported by Linux, PAE mode is implemented on all recent Intel
   9.496 +	  processors (Pentium Pro and better). NOTE: If you say "64GB" here,
   9.497 +	  then the kernel will not boot on CPUs that don't support PAE!
   9.498 +
   9.499 +	  The actual amount of total physical memory will either be
   9.500 +	  auto detected or can be forced by using a kernel command line option
   9.501 +	  such as "mem=256M". (Try "man bootparam" or see the documentation of
   9.502 +	  your boot loader (lilo or loadlin) about how to pass options to the
   9.503 +	  kernel at boot time.)
   9.504 +
   9.505 +	  If unsure, say "off".
   9.506 +
   9.507 +config HIGHMEM4G
   9.508 +	bool "4GB"
   9.509 +	help
   9.510 +	  Select this if you have a 32-bit processor and between 1 and 4
   9.511 +	  gigabytes of physical RAM.
   9.512 +
   9.513 +config HIGHMEM64G
   9.514 +	bool "64GB"
   9.515 +	help
   9.516 +	  Select this if you have a 32-bit processor and more than 4
   9.517 +	  gigabytes of physical RAM.
   9.518 +
   9.519 +endchoice
   9.520 +
   9.521 +config HIGHMEM
   9.522 +	bool
   9.523 +	depends on HIGHMEM64G || HIGHMEM4G
   9.524 +	default y
   9.525 +
   9.526 +config X86_PAE
   9.527 +	bool
   9.528 +	depends on HIGHMEM64G
   9.529 +	default y
   9.530 +
   9.531 +# Common NUMA Features
   9.532 +config NUMA
   9.533 +	bool "Numa Memory Allocation and Scheduler Support"
   9.534 +	depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI))
   9.535 +	default n if X86_PC
   9.536 +	default y if (X86_NUMAQ || X86_SUMMIT)
   9.537 +
   9.538 +# Need comments to help the hapless user trying to turn on NUMA support
   9.539 +comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
   9.540 +	depends on X86_NUMAQ && (!HIGHMEM64G || !SMP)
   9.541 +
   9.542 +comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
   9.543 +	depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
   9.544 +
   9.545 +config DISCONTIGMEM
   9.546 +	bool
   9.547 +	depends on NUMA
   9.548 +	default y
   9.549 +
   9.550 +config HAVE_ARCH_BOOTMEM_NODE
   9.551 +	bool
   9.552 +	depends on NUMA
   9.553 +	default y
   9.554 +
   9.555 +config HIGHPTE
   9.556 +	bool "Allocate 3rd-level pagetables from highmem"
   9.557 +	depends on HIGHMEM4G || HIGHMEM64G
   9.558 +	help
   9.559 +	  The VM uses one page table entry for each page of physical memory.
   9.560 +	  For systems with a lot of RAM, this can be wasteful of precious
   9.561 +	  low memory.  Setting this option will put user-space page table
   9.562 +	  entries in high memory.
   9.563 +
   9.564 +#config MTRR
   9.565 +#	 bool "MTRR (Memory Type Range Register) support"
   9.566 +#	 ---help---
   9.567 +#	   On Intel P6 family processors (Pentium Pro, Pentium II and later)
   9.568 +#	   the Memory Type Range Registers (MTRRs) may be used to control
   9.569 +#	   processor access to memory ranges. This is most useful if you have
   9.570 +#	   a video (VGA) card on a PCI or AGP bus. Enabling write-combining
   9.571 +#	   allows bus write transfers to be combined into a larger transfer
   9.572 +#	   before bursting over the PCI/AGP bus. This can increase performance
   9.573 +#	   of image write operations 2.5 times or more. Saying Y here creates a
   9.574 +#	   /proc/mtrr file which may be used to manipulate your processor's
   9.575 +#	   MTRRs. Typically the X server should use this.
   9.576 +#
   9.577 +#	   This code has a reasonably generic interface so that similar
   9.578 +#	   control registers on other processors can be easily supported
   9.579 +#	   as well:
   9.580 +#
   9.581 +#	   The Cyrix 6x86, 6x86MX and M II processors have Address Range
   9.582 +#	   Registers (ARRs) which provide a similar functionality to MTRRs. For
   9.583 +#	   these, the ARRs are used to emulate the MTRRs.
   9.584 +#	   The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
   9.585 +#	   MTRRs. The Centaur C6 (WinChip) has 8 MCRs, allowing
   9.586 +#	   write-combining. All of these processors are supported by this code
   9.587 +#	   and it makes sense to say Y here if you have one of them.
   9.588 +#
   9.589 +#	   Saying Y here also fixes a problem with buggy SMP BIOSes which only
   9.590 +#	   set the MTRRs for the boot CPU and not for the secondary CPUs. This
   9.591 +#	   can lead to all sorts of problems, so it's good to say Y here.
   9.592 +#
   9.593 +#	   You can safely say Y even if your machine doesn't have MTRRs, you'll
   9.594 +#	   just add about 9 KB to your kernel.
   9.595 +#
   9.596 +#	   See <file:Documentation/mtrr.txt> for more information.
   9.597 +
   9.598 +config IRQBALANCE
   9.599 + 	bool "Enable kernel irq balancing"
   9.600 +	depends on SMP && X86_IO_APIC
   9.601 +	default y
   9.602 +	help
   9.603 + 	  The default yes will allow the kernel to do irq load balancing.
   9.604 +	  Saying no will keep the kernel from doing irq load balancing.
   9.605 +
   9.606 +config HAVE_DEC_LOCK
   9.607 +	bool
   9.608 +	depends on (SMP || PREEMPT) && X86_CMPXCHG
   9.609 +	default y
   9.610 +
   9.611 +# turning this on wastes a bunch of space.
   9.612 +# Summit needs it only when NUMA is on
   9.613 +config BOOT_IOREMAP
   9.614 +	bool
   9.615 +	depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI))
   9.616 +	default y
   9.617 +
   9.618 +config REGPARM
   9.619 +	bool "Use register arguments (EXPERIMENTAL)"
   9.620 +	depends on EXPERIMENTAL
   9.621 +	default n
   9.622 +	help
   9.623 +	Compile the kernel with -mregparm=3. This uses an different ABI
   9.624 +	and passes the first three arguments of a function call in registers.
   9.625 +	This will probably break binary only modules.
   9.626 +
   9.627 +	This feature is only enabled for gcc-3.0 and later - earlier compilers
   9.628 +	generate incorrect output with certain kernel constructs when
   9.629 +	-mregparm=3 is used.
   9.630 +
   9.631 +
   9.632 +menu "Kernel hacking"
   9.633 +
   9.634 +config DEBUG_KERNEL
   9.635 +	bool "Kernel debugging"
   9.636 +	help
   9.637 +	  Say Y here if you are developing drivers or trying to debug and
   9.638 +	  identify kernel problems.
   9.639 +
   9.640 +config EARLY_PRINTK
   9.641 +	bool "Early printk" if EMBEDDED
   9.642 +	default y
   9.643 +	help
   9.644 +	  Write kernel log output directly into the VGA buffer or to a serial
   9.645 +	  port.
   9.646 +
   9.647 +	  This is useful for kernel debugging when your machine crashes very
   9.648 +	  early before the console code is initialized. For normal operation
   9.649 +	  it is not recommended because it looks ugly and doesn't cooperate
   9.650 +	  with klogd/syslogd or the X server. You should normally N here,
   9.651 +	  unless you want to debug such a crash.
   9.652 +
   9.653 +config DEBUG_STACKOVERFLOW
   9.654 +	bool "Check for stack overflows"
   9.655 +	depends on DEBUG_KERNEL
   9.656 +
   9.657 +config DEBUG_STACK_USAGE
   9.658 +	bool "Stack utilization instrumentation"
   9.659 +	depends on DEBUG_KERNEL
   9.660 +	help
   9.661 +	  Enables the display of the minimum amount of free stack which each
   9.662 +	  task has ever had available in the sysrq-T and sysrq-P debug output.
   9.663 +
   9.664 +	  This option will slow down process creation somewhat.
   9.665 +
   9.666 +config DEBUG_SLAB
   9.667 +	bool "Debug memory allocations"
   9.668 +	depends on DEBUG_KERNEL
   9.669 +	help
   9.670 +	  Say Y here to have the kernel do limited verification on memory
   9.671 +	  allocation as well as poisoning memory on free to catch use of freed
   9.672 +	  memory.
   9.673 +
   9.674 +config MAGIC_SYSRQ
   9.675 +	bool "Magic SysRq key"
   9.676 +	depends on DEBUG_KERNEL
   9.677 +	help
   9.678 +	  If you say Y here, you will have some control over the system even
   9.679 +	  if the system crashes for example during kernel debugging (e.g., you
   9.680 +	  will be able to flush the buffer cache to disk, reboot the system
   9.681 +	  immediately or dump some status information). This is accomplished
   9.682 +	  by pressing various keys while holding SysRq (Alt+PrintScreen). It
   9.683 +	  also works on a serial console (on PC hardware at least), if you
   9.684 +	  send a BREAK and then within 5 seconds a command keypress. The
   9.685 +	  keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   9.686 +	  unless you really know what this hack does.
   9.687 +
   9.688 +config DEBUG_SPINLOCK
   9.689 +	bool "Spinlock debugging"
   9.690 +	depends on DEBUG_KERNEL
   9.691 +	help
   9.692 +	  Say Y here and build SMP to catch missing spinlock initialization
   9.693 +	  and certain other kinds of spinlock errors commonly made.  This is
   9.694 +	  best used in conjunction with the NMI watchdog so that spinlock
   9.695 +	  deadlocks are also debuggable.
   9.696 +
   9.697 +config DEBUG_PAGEALLOC
   9.698 +	bool "Page alloc debugging"
   9.699 +	depends on DEBUG_KERNEL
   9.700 +	help
   9.701 +	  Unmap pages from the kernel linear mapping after free_pages().
   9.702 +	  This results in a large slowdown, but helps to find certain types
   9.703 +	  of memory corruptions.
   9.704 +
   9.705 +config DEBUG_HIGHMEM
   9.706 +	bool "Highmem debugging"
   9.707 +	depends on DEBUG_KERNEL && HIGHMEM
   9.708 +	help
   9.709 +	  This options enables addition error checking for high memory systems.
   9.710 +	  Disable for production systems.
   9.711 +
   9.712 +config DEBUG_INFO
   9.713 +	bool "Compile the kernel with debug info"
   9.714 +	depends on DEBUG_KERNEL
   9.715 +	help
   9.716 +          If you say Y here the resulting kernel image will include
   9.717 +	  debugging info resulting in a larger kernel image.
   9.718 +	  Say Y here only if you plan to use gdb to debug the kernel.
   9.719 +	  If you don't debug the kernel, you can say N.
   9.720 +	  
   9.721 +config DEBUG_SPINLOCK_SLEEP
   9.722 +	bool "Sleep-inside-spinlock checking"
   9.723 +	help
   9.724 +	  If you say Y here, various routines which may sleep will become very
   9.725 +	  noisy if they are called with a spinlock held.	
   9.726 +
   9.727 +config FRAME_POINTER
   9.728 +	bool "Compile the kernel with frame pointers"
   9.729 +	help
   9.730 +	  If you say Y here the resulting kernel image will be slightly larger
   9.731 +	  and slower, but it will give very useful debugging information.
   9.732 +	  If you don't debug the kernel, you can say N, but we may not be able
   9.733 +	  to solve problems without frame pointers.
   9.734 +
   9.735 +config 4KSTACKS
   9.736 +	bool "Use 4Kb for kernel stacks instead of 8Kb"
   9.737 +	help
   9.738 +	  If you say Y here the kernel will use a 4Kb stacksize for the
   9.739 +	  kernel stack attached to each process/thread. This facilitates
   9.740 +	  running more threads on a system and also reduces the pressure
   9.741 +	  on the VM subsystem for higher order allocations. This option
   9.742 +	  will also use IRQ stacks to compensate for the reduced stackspace.
   9.743 +
   9.744 +config X86_FIND_SMP_CONFIG
   9.745 +	bool
   9.746 +	depends on X86_LOCAL_APIC || X86_VOYAGER
   9.747 +	default y
   9.748 +
   9.749 +config X86_MPPARSE
   9.750 +	bool
   9.751 +	depends on X86_LOCAL_APIC && !X86_VISWS
   9.752 +	default y
   9.753 +
   9.754 +endmenu
   9.755 +
   9.756 +config X86_SMP
   9.757 +	bool
   9.758 +	depends on SMP && !X86_VOYAGER
   9.759 +	default y
   9.760 +
   9.761 +config X86_HT
   9.762 +	bool
   9.763 +	depends on SMP && !(X86_VISWS || X86_VOYAGER)
   9.764 +	default y
   9.765 +
   9.766 +config X86_BIOS_REBOOT
   9.767 +	bool
   9.768 +	depends on !(X86_VISWS || X86_VOYAGER)
   9.769 +	default y
   9.770 +
   9.771 +config X86_TRAMPOLINE
   9.772 +	bool
   9.773 +	depends on X86_SMP || (X86_VOYAGER && SMP)
   9.774 +	default y
   9.775 +
   9.776 +# std_resources is overridden for pc9800, but that's not
   9.777 +# a currently selectable arch choice
   9.778 +config X86_STD_RESOURCES
   9.779 +	bool
   9.780 +	default y
   9.781 +
   9.782 +config PC
   9.783 +	bool
   9.784 +	depends on X86 && !EMBEDDED
   9.785 +	default y
   9.786 +
   9.787 +endmenu
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/Makefile	Wed Jul 14 16:41:41 2004 +0000
    10.3 @@ -0,0 +1,97 @@
    10.4 +#
    10.5 +# i386/Makefile
    10.6 +#
    10.7 +# This file is included by the global makefile so that you can add your own
    10.8 +# architecture-specific flags and dependencies. Remember to do have actions
    10.9 +# for "archclean" cleaning up for this architecture.
   10.10 +#
   10.11 +# This file is subject to the terms and conditions of the GNU General Public
   10.12 +# License.  See the file "COPYING" in the main directory of this archive
   10.13 +# for more details.
   10.14 +#
   10.15 +# Copyright (C) 1994 by Linus Torvalds
   10.16 +#
   10.17 +# 19990713  Artur Skawina <skawina@geocities.com>
   10.18 +#           Added '-march' and '-mpreferred-stack-boundary' support
   10.19 +#
   10.20 +
   10.21 +XENARCH	:= $(subst ",,$(CONFIG_XENARCH))
   10.22 +
   10.23 +LDFLAGS		:= -m elf_i386
   10.24 +LDFLAGS_vmlinux :=
   10.25 +CHECK		:= $(CHECK) -D__i386__=1
   10.26 +
   10.27 +CFLAGS += -pipe -msoft-float
   10.28 +
   10.29 +# prevent gcc from keeping the stack 16 byte aligned
   10.30 +CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,)
   10.31 +
   10.32 +align := $(subst -functions=0,,$(call check_gcc,-falign-functions=0,-malign-functions=0))
   10.33 +
   10.34 +cflags-$(CONFIG_M386)		+= -march=i386
   10.35 +cflags-$(CONFIG_M486)		+= -march=i486
   10.36 +cflags-$(CONFIG_M586)		+= -march=i586
   10.37 +cflags-$(CONFIG_M586TSC)	+= -march=i586
   10.38 +cflags-$(CONFIG_M586MMX)	+= $(call check_gcc,-march=pentium-mmx,-march=i586)
   10.39 +cflags-$(CONFIG_M686)		+= -march=i686
   10.40 +cflags-$(CONFIG_MPENTIUMII)	+= $(call check_gcc,-march=pentium2,-march=i686)
   10.41 +cflags-$(CONFIG_MPENTIUMIII)	+= $(call check_gcc,-march=pentium3,-march=i686)
   10.42 +cflags-$(CONFIG_MPENTIUMM)	+= $(call check_gcc,-march=pentium3,-march=i686)
   10.43 +cflags-$(CONFIG_MPENTIUM4)	+= $(call check_gcc,-march=pentium4,-march=i686)
   10.44 +cflags-$(CONFIG_MK6)		+= -march=k6
   10.45 +# Please note, that patches that add -march=athlon-xp and friends are pointless.
   10.46 +# They make zero difference whatsosever to performance at this time.
   10.47 +cflags-$(CONFIG_MK7)		+= $(call check_gcc,-march=athlon,-march=i686 $(align)-functions=4)
   10.48 +cflags-$(CONFIG_MK8)		+= $(call check_gcc,-march=k8,$(call check_gcc,-march=athlon,-march=i686 $(align)-functions=4))
   10.49 +cflags-$(CONFIG_MCRUSOE)	+= -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
   10.50 +cflags-$(CONFIG_MWINCHIPC6)	+= $(call check_gcc,-march=winchip-c6,-march=i586)
   10.51 +cflags-$(CONFIG_MWINCHIP2)	+= $(call check_gcc,-march=winchip2,-march=i586)
   10.52 +cflags-$(CONFIG_MWINCHIP3D)	+= $(call check_gcc,-march=winchip2,-march=i586)
   10.53 +cflags-$(CONFIG_MCYRIXIII)	+= $(call check_gcc,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
   10.54 +cflags-$(CONFIG_MVIAC3_2)	+= $(call check_gcc,-march=c3-2,-march=i686)
   10.55 +
   10.56 +# AMD Elan support
   10.57 +cflags-$(CONFIG_X86_ELAN)	+= -march=i486
   10.58 +
   10.59 +# -mregparm=3 works ok on gcc-3.0 and later
   10.60 +#
   10.61 +GCC_VERSION			:= $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
   10.62 +cflags-$(CONFIG_REGPARM) 	+= $(shell if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)
   10.63 +
   10.64 +# Disable unit-at-a-time mode, it makes gcc use a lot more stack
   10.65 +# due to the lack of sharing of stacklots.
   10.66 +CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
   10.67 +
   10.68 +CFLAGS += $(cflags-y)
   10.69 +
   10.70 +head-y := arch/xen/i386/kernel/head.o arch/xen/i386/kernel/init_task.o
   10.71 +
   10.72 +libs-y 					+= arch/i386/lib/
   10.73 +core-y					+= arch/xen/i386/kernel/ \
   10.74 +					   arch/xen/i386/mm/
   10.75 +# \
   10.76 +#					   arch/xen/$(mcore-y)/
   10.77 +drivers-$(CONFIG_MATH_EMULATION)	+= arch/i386/math-emu/
   10.78 +drivers-$(CONFIG_PCI)			+= arch/i386/pci/
   10.79 +# must be linked after kernel/
   10.80 +drivers-$(CONFIG_OPROFILE)		+= arch/i386/oprofile/
   10.81 +drivers-$(CONFIG_PM)			+= arch/i386/power/
   10.82 +
   10.83 +# for clean
   10.84 +obj-	+= kernel/
   10.85 +#obj-	+= ../../i386/lib/ ../../i386/mm/ 
   10.86 +#../../i386/$(mcore-y)/
   10.87 +#obj-	+= ../../i386/pci/ ../../i386/oprofile/ ../../i386/power/
   10.88 +
   10.89 +xenflags-y += -Iinclude/asm-xen/asm-i386/mach-xen
   10.90 +CFLAGS += $(xenflags-y)
   10.91 +AFLAGS += $(xenflags-y)
   10.92 +
   10.93 +prepare: include/asm-$(XENARCH)/asm_offsets.h
   10.94 +CLEAN_FILES += include/asm-$(XENARCH)/asm_offsets.h
   10.95 +
   10.96 +arch/$(XENARCH)/kernel/asm-offsets.s: include/asm include/.asm-ignore \
   10.97 +	include/linux/version.h include/config/MARKER
   10.98 +
   10.99 +include/asm-$(XENARCH)/asm_offsets.h: arch/$(XENARCH)/kernel/asm-offsets.s
  10.100 +	$(call filechk,gen-asm-offsets)
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/Makefile	Wed Jul 14 16:41:41 2004 +0000
    11.3 @@ -0,0 +1,94 @@
    11.4 +#
    11.5 +# Makefile for the linux kernel.
    11.6 +#
    11.7 +
    11.8 +XENARCH	:= $(subst ",,$(CONFIG_XENARCH))
    11.9 +
   11.10 +CFLAGS	+= -Iarch/$(XENARCH)/kernel
   11.11 +
   11.12 +extra-y := head.o init_task.o vmlinux.lds.s
   11.13 +
   11.14 +obj-y	:= traps.o irq.o ldt.o setup.o entry.o time.o process.o signal.o
   11.15 +
   11.16 +c-obj-y	:= semaphore.o vm86.o \
   11.17 +		ptrace.o ioport.o sys_i386.o \
   11.18 +		pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
   11.19 +		doublefault.o
   11.20 +s-obj-y	:=
   11.21 +
   11.22 +#obj-y				+= hypervisor.o
   11.23 +obj-y				+= evtchn.o
   11.24 +
   11.25 +obj-y				+= cpu/
   11.26 +obj-y				+= timers/
   11.27 +c-obj-$(CONFIG_ACPI_BOOT)	+= acpi/
   11.28 +#c-obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
   11.29 +c-obj-$(CONFIG_MCA)		+= mca.o
   11.30 +c-obj-$(CONFIG_X86_MSR)		+= msr.o
   11.31 +c-obj-$(CONFIG_X86_CPUID)	+= cpuid.o
   11.32 +c-obj-$(CONFIG_MICROCODE)	+= microcode.o
   11.33 +c-obj-$(CONFIG_APM)		+= apm.o
   11.34 +c-obj-$(CONFIG_X86_SMP)		+= smp.o smpboot.o
   11.35 +c-obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline.o
   11.36 +c-obj-$(CONFIG_X86_MPPARSE)	+= mpparse.o
   11.37 +c-obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o nmi.o
   11.38 +c-obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
   11.39 +c-obj-$(CONFIG_X86_NUMAQ)	+= numaq.o
   11.40 +c-obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.o
   11.41 +c-obj-$(CONFIG_MODULES)		+= module.o
   11.42 +obj-y				+= sysenter.o
   11.43 +obj-y				+= vsyscall.o
   11.44 +c-obj-$(CONFIG_ACPI_SRAT) 	+= srat.o
   11.45 +c-obj-$(CONFIG_HPET_TIMER) 	+= time_hpet.o
   11.46 +c-obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
   11.47 +c-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
   11.48 +c-obj-$(CONFIG_X86_STD_RESOURCES)	+= std_resources.o
   11.49 +
   11.50 +EXTRA_AFLAGS   := -traditional
   11.51 +
   11.52 +c-obj-$(CONFIG_SCx200)		+= scx200.o
   11.53 +
   11.54 +AFLAGS_vmlinux.lds.o += -U$(XENARCH)
   11.55 +
   11.56 +# vsyscall.o contains the vsyscall DSO images as __initdata.
   11.57 +# We must build both images before we can assemble it.
   11.58 +# Note: kbuild does not track this dependency due to usage of .incbin
   11.59 +$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
   11.60 +targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
   11.61 +
   11.62 +# The DSO images are built using a special linker script.
   11.63 +quiet_cmd_syscall = SYSCALL $@
   11.64 +      cmd_syscall = $(CC) -nostdlib $(SYSCFLAGS_$(@F)) \
   11.65 +		          -Wl,-T,$(filter-out FORCE,$^) -o $@
   11.66 +
   11.67 +vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1
   11.68 +SYSCFLAGS_vsyscall-sysenter.so	= $(vsyscall-flags)
   11.69 +SYSCFLAGS_vsyscall-int80.so	= $(vsyscall-flags)
   11.70 +
   11.71 +$(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \
   11.72 +$(obj)/vsyscall-%.so: $(obj)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
   11.73 +	$(call if_changed,syscall)
   11.74 +
   11.75 +# We also create a special relocatable object that should mirror the symbol
   11.76 +# table and layout of the linked DSO.  With ld -R we can then refer to
   11.77 +# these symbols in the kernel code rather than hand-coded addresses.
   11.78 +extra-y += vsyscall-syms.o
   11.79 +$(obj)/built-in.o: $(obj)/vsyscall-syms.o
   11.80 +$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
   11.81 +
   11.82 +SYSCFLAGS_vsyscall-syms.o = -r
   11.83 +$(obj)/vsyscall-syms.o: $(obj)/vsyscall.lds $(obj)/vsyscall-sysenter.o FORCE
   11.84 +	$(call if_changed,syscall)
   11.85 +
   11.86 +c-link	:= init_task.o
   11.87 +s-link	:= vsyscall-int80.o vsyscall-sysenter.o vsyscall-sigreturn.o
   11.88 +
   11.89 +$(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)) $(patsubst %.o,$(obj)/%.S,$(s-obj-y) $(s-link)):
   11.90 +	@ln -fsn $(srctree)/arch/i386/kernel/$(notdir $@) $@
   11.91 +
   11.92 +$(obj)/vsyscall-int80.S: $(obj)/vsyscall-sigreturn.S
   11.93 +
   11.94 +obj-y	+= $(c-obj-y) $(s-obj-y)
   11.95 +
   11.96 +clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link))
   11.97 +clean-files += $(patsubst %.o,%.S,$(s-obj-y) $(s-obj-) $(s-link))
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/cpu/Makefile	Wed Jul 14 16:41:41 2004 +0000
    12.3 @@ -0,0 +1,31 @@
    12.4 +#
    12.5 +# Makefile for x86-compatible CPU details and quirks
    12.6 +#
    12.7 +
    12.8 +CFLAGS	+= -Iarch/i386/kernel/cpu
    12.9 +
   12.10 +obj-y	:=	common.o
   12.11 +c-obj-y	+=	proc.o
   12.12 +
   12.13 +c-obj-y	+=	amd.o
   12.14 +c-obj-y	+=	cyrix.o
   12.15 +c-obj-y	+=	centaur.o
   12.16 +c-obj-y	+=	transmeta.o
   12.17 +c-obj-y	+=	intel.o
   12.18 +c-obj-y	+=	rise.o
   12.19 +c-obj-y	+=	nexgen.o
   12.20 +c-obj-y	+=	umc.o
   12.21 +
   12.22 +#obj-$(CONFIG_X86_MCE)	+=	../../../../i386/kernel/cpu/mcheck/
   12.23 +
   12.24 +#obj-$(CONFIG_MTRR)	+= 	../../../../i386/kernel/cpu/mtrr/
   12.25 +#obj-$(CONFIG_CPU_FREQ)	+=	../../../../i386/kernel/cpu/cpufreq/
   12.26 +
   12.27 +c-link	:=
   12.28 +
   12.29 +$(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)):
   12.30 +	@ln -fsn $(srctree)/arch/i386/kernel/cpu/$(notdir $@) $@
   12.31 +
   12.32 +obj-y	+= $(c-obj-y)
   12.33 +
   12.34 +clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link))
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Wed Jul 14 16:41:41 2004 +0000
    13.3 @@ -0,0 +1,597 @@
    13.4 +#include <linux/init.h>
    13.5 +#include <linux/string.h>
    13.6 +#include <linux/delay.h>
    13.7 +#include <linux/smp.h>
    13.8 +#include <asm/semaphore.h>
    13.9 +#include <asm/processor.h>
   13.10 +#include <asm/i387.h>
   13.11 +#include <asm/msr.h>
   13.12 +#include <asm/io.h>
   13.13 +#include <asm/mmu_context.h>
   13.14 +#include <asm/hypervisor.h>
   13.15 +
   13.16 +#include "cpu.h"
   13.17 +
   13.18 +static int cachesize_override __initdata = -1;
   13.19 +static int disable_x86_fxsr __initdata = 0;
   13.20 +static int disable_x86_serial_nr __initdata = 1;
   13.21 +
   13.22 +struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
   13.23 +
   13.24 +extern void mcheck_init(struct cpuinfo_x86 *c);
   13.25 +
   13.26 +extern int disable_pse;
   13.27 +
   13.28 +static void default_init(struct cpuinfo_x86 * c)
   13.29 +{
   13.30 +	/* Not much we can do here... */
   13.31 +	/* Check if at least it has cpuid */
   13.32 +	if (c->cpuid_level == -1) {
   13.33 +		/* No cpuid. It must be an ancient CPU */
   13.34 +		if (c->x86 == 4)
   13.35 +			strcpy(c->x86_model_id, "486");
   13.36 +		else if (c->x86 == 3)
   13.37 +			strcpy(c->x86_model_id, "386");
   13.38 +	}
   13.39 +}
   13.40 +
   13.41 +static struct cpu_dev default_cpu = {
   13.42 +	.c_init	= default_init,
   13.43 +};
   13.44 +static struct cpu_dev * this_cpu = &default_cpu;
   13.45 +
   13.46 +static int __init cachesize_setup(char *str)
   13.47 +{
   13.48 +	get_option (&str, &cachesize_override);
   13.49 +	return 1;
   13.50 +}
   13.51 +__setup("cachesize=", cachesize_setup);
   13.52 +
   13.53 +int __init get_model_name(struct cpuinfo_x86 *c)
   13.54 +{
   13.55 +	unsigned int *v;
   13.56 +	char *p, *q;
   13.57 +
   13.58 +	if (cpuid_eax(0x80000000) < 0x80000004)
   13.59 +		return 0;
   13.60 +
   13.61 +	v = (unsigned int *) c->x86_model_id;
   13.62 +	cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
   13.63 +	cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
   13.64 +	cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
   13.65 +	c->x86_model_id[48] = 0;
   13.66 +
   13.67 +	/* Intel chips right-justify this string for some dumb reason;
   13.68 +	   undo that brain damage */
   13.69 +	p = q = &c->x86_model_id[0];
   13.70 +	while ( *p == ' ' )
   13.71 +	     p++;
   13.72 +	if ( p != q ) {
   13.73 +	     while ( *p )
   13.74 +		  *q++ = *p++;
   13.75 +	     while ( q <= &c->x86_model_id[48] )
   13.76 +		  *q++ = '\0';	/* Zero-pad the rest */
   13.77 +	}
   13.78 +
   13.79 +	return 1;
   13.80 +}
   13.81 +
   13.82 +
   13.83 +void __init display_cacheinfo(struct cpuinfo_x86 *c)
   13.84 +{
   13.85 +	unsigned int n, dummy, ecx, edx, l2size;
   13.86 +
   13.87 +	n = cpuid_eax(0x80000000);
   13.88 +
   13.89 +	if (n >= 0x80000005) {
   13.90 +		cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
   13.91 +		printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
   13.92 +			edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
   13.93 +		c->x86_cache_size=(ecx>>24)+(edx>>24);	
   13.94 +	}
   13.95 +
   13.96 +	if (n < 0x80000006)	/* Some chips just has a large L1. */
   13.97 +		return;
   13.98 +
   13.99 +	ecx = cpuid_ecx(0x80000006);
  13.100 +	l2size = ecx >> 16;
  13.101 +	
  13.102 +	/* do processor-specific cache resizing */
  13.103 +	if (this_cpu->c_size_cache)
  13.104 +		l2size = this_cpu->c_size_cache(c,l2size);
  13.105 +
  13.106 +	/* Allow user to override all this if necessary. */
  13.107 +	if (cachesize_override != -1)
  13.108 +		l2size = cachesize_override;
  13.109 +
  13.110 +	if ( l2size == 0 )
  13.111 +		return;		/* Again, no L2 cache is possible */
  13.112 +
  13.113 +	c->x86_cache_size = l2size;
  13.114 +
  13.115 +	printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
  13.116 +	       l2size, ecx & 0xFF);
  13.117 +}
  13.118 +
  13.119 +/* Naming convention should be: <Name> [(<Codename>)] */
  13.120 +/* This table only is used unless init_<vendor>() below doesn't set it; */
  13.121 +/* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */
  13.122 +
  13.123 +/* Look up CPU names by table lookup. */
  13.124 +static char __init *table_lookup_model(struct cpuinfo_x86 *c)
  13.125 +{
  13.126 +	struct cpu_model_info *info;
  13.127 +
  13.128 +	if ( c->x86_model >= 16 )
  13.129 +		return NULL;	/* Range check */
  13.130 +
  13.131 +	if (!this_cpu)
  13.132 +		return NULL;
  13.133 +
  13.134 +	info = this_cpu->c_models;
  13.135 +
  13.136 +	while (info && info->family) {
  13.137 +		if (info->family == c->x86)
  13.138 +			return info->model_names[c->x86_model];
  13.139 +		info++;
  13.140 +	}
  13.141 +	return NULL;		/* Not found */
  13.142 +}
  13.143 +
  13.144 +
  13.145 +void __init get_cpu_vendor(struct cpuinfo_x86 *c, int early)
  13.146 +{
  13.147 +	char *v = c->x86_vendor_id;
  13.148 +	int i;
  13.149 +
  13.150 +	for (i = 0; i < X86_VENDOR_NUM; i++) {
  13.151 +		if (cpu_devs[i]) {
  13.152 +			if (!strcmp(v,cpu_devs[i]->c_ident[0]) ||
  13.153 +			    (cpu_devs[i]->c_ident[1] && 
  13.154 +			     !strcmp(v,cpu_devs[i]->c_ident[1]))) {
  13.155 +				c->x86_vendor = i;
  13.156 +				if (!early)
  13.157 +					this_cpu = cpu_devs[i];
  13.158 +				break;
  13.159 +			}
  13.160 +		}
  13.161 +	}
  13.162 +}
  13.163 +
  13.164 +
  13.165 +static int __init x86_fxsr_setup(char * s)
  13.166 +{
  13.167 +	disable_x86_fxsr = 1;
  13.168 +	return 1;
  13.169 +}
  13.170 +__setup("nofxsr", x86_fxsr_setup);
  13.171 +
  13.172 +
  13.173 +/* Standard macro to see if a specific flag is changeable */
  13.174 +static inline int flag_is_changeable_p(u32 flag)
  13.175 +{
  13.176 +	u32 f1, f2;
  13.177 +
  13.178 +	asm("pushfl\n\t"
  13.179 +	    "pushfl\n\t"
  13.180 +	    "popl %0\n\t"
  13.181 +	    "movl %0,%1\n\t"
  13.182 +	    "xorl %2,%0\n\t"
  13.183 +	    "pushl %0\n\t"
  13.184 +	    "popfl\n\t"
  13.185 +	    "pushfl\n\t"
  13.186 +	    "popl %0\n\t"
  13.187 +	    "popfl\n\t"
  13.188 +	    : "=&r" (f1), "=&r" (f2)
  13.189 +	    : "ir" (flag));
  13.190 +
  13.191 +	return ((f1^f2) & flag) != 0;
  13.192 +}
  13.193 +
  13.194 +
  13.195 +/* Probe for the CPUID instruction */
  13.196 +int __init have_cpuid_p(void)
  13.197 +{
  13.198 +	return flag_is_changeable_p(X86_EFLAGS_ID);
  13.199 +}
  13.200 +
  13.201 +/* Do minimum CPU detection early.
  13.202 +   Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment.
  13.203 +   The others are not touched to avoid unwanted side effects. */
  13.204 +void __init early_cpu_detect(void)
  13.205 +{
  13.206 +	struct cpuinfo_x86 *c = &boot_cpu_data;
  13.207 +
  13.208 +	c->x86_cache_alignment = 32;
  13.209 +
  13.210 +	if (!have_cpuid_p())
  13.211 +		return;
  13.212 +
  13.213 +	/* Get vendor name */
  13.214 +	cpuid(0x00000000, &c->cpuid_level,
  13.215 +	      (int *)&c->x86_vendor_id[0],
  13.216 +	      (int *)&c->x86_vendor_id[8],
  13.217 +	      (int *)&c->x86_vendor_id[4]);
  13.218 +
  13.219 +	get_cpu_vendor(c, 1);
  13.220 +
  13.221 +	c->x86 = 4;
  13.222 +	if (c->cpuid_level >= 0x00000001) {
  13.223 +		u32 junk, tfms, cap0, misc;
  13.224 +		cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
  13.225 +		c->x86 = (tfms >> 8) & 15;
  13.226 +		c->x86_model = (tfms >> 4) & 15;
  13.227 +		if (c->x86 == 0xf) {
  13.228 +			c->x86 += (tfms >> 20) & 0xff;
  13.229 +			c->x86_model += ((tfms >> 16) & 0xF) << 4;
  13.230 +		}
  13.231 +		c->x86_mask = tfms & 15;
  13.232 +		if (cap0 & (1<<19))
  13.233 +			c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;
  13.234 +	}
  13.235 +
  13.236 +	early_intel_workaround(c);
  13.237 +}
  13.238 +
  13.239 +void __init generic_identify(struct cpuinfo_x86 * c)
  13.240 +{
  13.241 +	u32 tfms, xlvl;
  13.242 +	int junk;
  13.243 +
  13.244 +	if (have_cpuid_p()) {
  13.245 +		/* Get vendor name */
  13.246 +		cpuid(0x00000000, &c->cpuid_level,
  13.247 +		      (int *)&c->x86_vendor_id[0],
  13.248 +		      (int *)&c->x86_vendor_id[8],
  13.249 +		      (int *)&c->x86_vendor_id[4]);
  13.250 +		
  13.251 +		get_cpu_vendor(c, 0);
  13.252 +		/* Initialize the standard set of capabilities */
  13.253 +		/* Note that the vendor-specific code below might override */
  13.254 +	
  13.255 +		/* Intel-defined flags: level 0x00000001 */
  13.256 +		if ( c->cpuid_level >= 0x00000001 ) {
  13.257 +			u32 capability, excap;
  13.258 +			cpuid(0x00000001, &tfms, &junk, &excap, &capability);
  13.259 +			c->x86_capability[0] = capability;
  13.260 +			c->x86_capability[4] = excap;
  13.261 +			c->x86 = (tfms >> 8) & 15;
  13.262 +			c->x86_model = (tfms >> 4) & 15;
  13.263 +			if (c->x86 == 0xf) {
  13.264 +				c->x86 += (tfms >> 20) & 0xff;
  13.265 +				c->x86_model += ((tfms >> 16) & 0xF) << 4;
  13.266 +			} 
  13.267 +			c->x86_mask = tfms & 15;
  13.268 +		} else {
  13.269 +			/* Have CPUID level 0 only - unheard of */
  13.270 +			c->x86 = 4;
  13.271 +		}
  13.272 +
  13.273 +		/* AMD-defined flags: level 0x80000001 */
  13.274 +		xlvl = cpuid_eax(0x80000000);
  13.275 +		if ( (xlvl & 0xffff0000) == 0x80000000 ) {
  13.276 +			if ( xlvl >= 0x80000001 )
  13.277 +				c->x86_capability[1] = cpuid_edx(0x80000001);
  13.278 +			if ( xlvl >= 0x80000004 )
  13.279 +				get_model_name(c); /* Default name */
  13.280 +		}
  13.281 +	}
  13.282 +}
  13.283 +
  13.284 +static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
  13.285 +{
  13.286 +	if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) {
  13.287 +		/* Disable processor serial number */
  13.288 +		unsigned long lo,hi;
  13.289 +		rdmsr(MSR_IA32_BBL_CR_CTL,lo,hi);
  13.290 +		lo |= 0x200000;
  13.291 +		wrmsr(MSR_IA32_BBL_CR_CTL,lo,hi);
  13.292 +		printk(KERN_NOTICE "CPU serial number disabled.\n");
  13.293 +		clear_bit(X86_FEATURE_PN, c->x86_capability);
  13.294 +
  13.295 +		/* Disabling the serial number may affect the cpuid level */
  13.296 +		c->cpuid_level = cpuid_eax(0);
  13.297 +	}
  13.298 +}
  13.299 +
  13.300 +static int __init x86_serial_nr_setup(char *s)
  13.301 +{
  13.302 +	disable_x86_serial_nr = 0;
  13.303 +	return 1;
  13.304 +}
  13.305 +__setup("serialnumber", x86_serial_nr_setup);
  13.306 +
  13.307 +
  13.308 +
  13.309 +/*
  13.310 + * This does the hard work of actually picking apart the CPU stuff...
  13.311 + */
  13.312 +void __init identify_cpu(struct cpuinfo_x86 *c)
  13.313 +{
  13.314 +	int i;
  13.315 +
  13.316 +	c->loops_per_jiffy = loops_per_jiffy;
  13.317 +	c->x86_cache_size = -1;
  13.318 +	c->x86_vendor = X86_VENDOR_UNKNOWN;
  13.319 +	c->cpuid_level = -1;	/* CPUID not detected */
  13.320 +	c->x86_model = c->x86_mask = 0;	/* So far unknown... */
  13.321 +	c->x86_vendor_id[0] = '\0'; /* Unset */
  13.322 +	c->x86_model_id[0] = '\0';  /* Unset */
  13.323 +	memset(&c->x86_capability, 0, sizeof c->x86_capability);
  13.324 +
  13.325 +	if (!have_cpuid_p()) {
  13.326 +		/* First of all, decide if this is a 486 or higher */
  13.327 +		/* It's a 486 if we can modify the AC flag */
  13.328 +		if ( flag_is_changeable_p(X86_EFLAGS_AC) )
  13.329 +			c->x86 = 4;
  13.330 +		else
  13.331 +			c->x86 = 3;
  13.332 +	}
  13.333 +
  13.334 +	generic_identify(c);
  13.335 +
  13.336 +	printk(KERN_DEBUG "CPU:     After generic identify, caps: %08lx %08lx %08lx %08lx\n",
  13.337 +		c->x86_capability[0],
  13.338 +		c->x86_capability[1],
  13.339 +		c->x86_capability[2],
  13.340 +		c->x86_capability[3]);
  13.341 +
  13.342 +	if (this_cpu->c_identify) {
  13.343 +		this_cpu->c_identify(c);
  13.344 +
  13.345 +	printk(KERN_DEBUG "CPU:     After vendor identify, caps: %08lx %08lx %08lx %08lx\n",
  13.346 +		c->x86_capability[0],
  13.347 +		c->x86_capability[1],
  13.348 +		c->x86_capability[2],
  13.349 +		c->x86_capability[3]);
  13.350 +}
  13.351 +
  13.352 +	/*
  13.353 +	 * Vendor-specific initialization.  In this section we
  13.354 +	 * canonicalize the feature flags, meaning if there are
  13.355 +	 * features a certain CPU supports which CPUID doesn't
  13.356 +	 * tell us, CPUID claiming incorrect flags, or other bugs,
  13.357 +	 * we handle them here.
  13.358 +	 *
  13.359 +	 * At the end of this section, c->x86_capability better
  13.360 +	 * indicate the features this CPU genuinely supports!
  13.361 +	 */
  13.362 +	if (this_cpu->c_init)
  13.363 +		this_cpu->c_init(c);
  13.364 +
  13.365 +	/* Disable the PN if appropriate */
  13.366 +	squash_the_stupid_serial_number(c);
  13.367 +
  13.368 +	/*
  13.369 +	 * The vendor-specific functions might have changed features.  Now
  13.370 +	 * we do "generic changes."
  13.371 +	 */
  13.372 +
  13.373 +	/* TSC disabled? */
  13.374 +	if ( tsc_disable )
  13.375 +		clear_bit(X86_FEATURE_TSC, c->x86_capability);
  13.376 +
  13.377 +	/* FXSR disabled? */
  13.378 +	if (disable_x86_fxsr) {
  13.379 +		clear_bit(X86_FEATURE_FXSR, c->x86_capability);
  13.380 +		clear_bit(X86_FEATURE_XMM, c->x86_capability);
  13.381 +	}
  13.382 +
  13.383 +	if (disable_pse)
  13.384 +		clear_bit(X86_FEATURE_PSE, c->x86_capability);
  13.385 +
  13.386 +	/* If the model name is still unset, do table lookup. */
  13.387 +	if ( !c->x86_model_id[0] ) {
  13.388 +		char *p;
  13.389 +		p = table_lookup_model(c);
  13.390 +		if ( p )
  13.391 +			strcpy(c->x86_model_id, p);
  13.392 +		else
  13.393 +			/* Last resort... */
  13.394 +			sprintf(c->x86_model_id, "%02x/%02x",
  13.395 +				c->x86_vendor, c->x86_model);
  13.396 +	}
  13.397 +
  13.398 +	/* Now the feature flags better reflect actual CPU features! */
  13.399 +
  13.400 +	printk(KERN_DEBUG "CPU:     After all inits, caps: %08lx %08lx %08lx %08lx\n",
  13.401 +	       c->x86_capability[0],
  13.402 +	       c->x86_capability[1],
  13.403 +	       c->x86_capability[2],
  13.404 +	       c->x86_capability[3]);
  13.405 +
  13.406 +	/*
  13.407 +	 * On SMP, boot_cpu_data holds the common feature set between
  13.408 +	 * all CPUs; so make sure that we indicate which features are
  13.409 +	 * common between the CPUs.  The first time this routine gets
  13.410 +	 * executed, c == &boot_cpu_data.
  13.411 +	 */
  13.412 +	if ( c != &boot_cpu_data ) {
  13.413 +		/* AND the already accumulated flags with these */
  13.414 +		for ( i = 0 ; i < NCAPINTS ; i++ )
  13.415 +			boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
  13.416 +	}
  13.417 +
  13.418 +	/* Init Machine Check Exception if available. */
  13.419 +#ifdef CONFIG_X86_MCE
  13.420 +	mcheck_init(c);
  13.421 +#endif
  13.422 +}
  13.423 +/*
  13.424 + *	Perform early boot up checks for a valid TSC. See arch/i386/kernel/time.c
  13.425 + */
  13.426 + 
  13.427 +void __init dodgy_tsc(void)
  13.428 +{
  13.429 +	if (( boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX ) ||
  13.430 +	    ( boot_cpu_data.x86_vendor == X86_VENDOR_NSC   ))
  13.431 +		cpu_devs[X86_VENDOR_CYRIX]->c_init(&boot_cpu_data);
  13.432 +}
  13.433 +
  13.434 +void __init print_cpu_info(struct cpuinfo_x86 *c)
  13.435 +{
  13.436 +	char *vendor = NULL;
  13.437 +
  13.438 +	if (c->x86_vendor < X86_VENDOR_NUM)
  13.439 +		vendor = this_cpu->c_vendor;
  13.440 +	else if (c->cpuid_level >= 0)
  13.441 +		vendor = c->x86_vendor_id;
  13.442 +
  13.443 +	if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor)))
  13.444 +		printk("%s ", vendor);
  13.445 +
  13.446 +	if (!c->x86_model_id[0])
  13.447 +		printk("%d86", c->x86);
  13.448 +	else
  13.449 +		printk("%s", c->x86_model_id);
  13.450 +
  13.451 +	if (c->x86_mask || c->cpuid_level >= 0) 
  13.452 +		printk(" stepping %02x\n", c->x86_mask);
  13.453 +	else
  13.454 +		printk("\n");
  13.455 +}
  13.456 +
  13.457 +unsigned long cpu_initialized __initdata = 0;
  13.458 +
  13.459 +/* This is hacky. :)
  13.460 + * We're emulating future behavior.
  13.461 + * In the future, the cpu-specific init functions will be called implicitly
  13.462 + * via the magic of initcalls.
  13.463 + * They will insert themselves into the cpu_devs structure.
  13.464 + * Then, when cpu_init() is called, we can just iterate over that array.
  13.465 + */
  13.466 +
  13.467 +extern int intel_cpu_init(void);
  13.468 +extern int cyrix_init_cpu(void);
  13.469 +extern int nsc_init_cpu(void);
  13.470 +extern int amd_init_cpu(void);
  13.471 +extern int centaur_init_cpu(void);
  13.472 +extern int transmeta_init_cpu(void);
  13.473 +extern int rise_init_cpu(void);
  13.474 +extern int nexgen_init_cpu(void);
  13.475 +extern int umc_init_cpu(void);
  13.476 +void early_cpu_detect(void);
  13.477 +
  13.478 +void __init early_cpu_init(void)
  13.479 +{
  13.480 +	early_cpu_detect();
  13.481 +	intel_cpu_init();
  13.482 +	cyrix_init_cpu();
  13.483 +	nsc_init_cpu();
  13.484 +	amd_init_cpu();
  13.485 +	centaur_init_cpu();
  13.486 +	transmeta_init_cpu();
  13.487 +	rise_init_cpu();
  13.488 +	nexgen_init_cpu();
  13.489 +	umc_init_cpu();
  13.490 +
  13.491 +#ifdef CONFIG_DEBUG_PAGEALLOC
  13.492 +	/* pse is not compatible with on-the-fly unmapping,
  13.493 +	 * disable it even if the cpus claim to support it.
  13.494 +	 */
  13.495 +	clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
  13.496 +	disable_pse = 1;
  13.497 +#endif
  13.498 +}
  13.499 +
  13.500 +void __init cpu_gdt_init(struct Xgt_desc_struct *gdt_descr)
  13.501 +{
  13.502 +	unsigned long frames[gdt_descr->size >> PAGE_SHIFT];
  13.503 +	unsigned long va;
  13.504 +	int f;
  13.505 +
  13.506 +	for (va = gdt_descr->address, f = 0;
  13.507 +	     va < gdt_descr->address + gdt_descr->size;
  13.508 +	     va += PAGE_SIZE, f++) {
  13.509 +		frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
  13.510 +		wrprotect_bootpt(swapper_pg_dir, (void *)va, 1);
  13.511 +	}
  13.512 +	flush_page_update_queue();
  13.513 +	if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8))
  13.514 +		BUG();
  13.515 +	lgdt_finish();
  13.516 +}
  13.517 +
  13.518 +/*
  13.519 + * cpu_init() initializes state that is per-CPU. Some data is already
  13.520 + * initialized (naturally) in the bootstrap process, such as the GDT
  13.521 + * and IDT. We reload them nevertheless, this function acts as a
  13.522 + * 'CPU state barrier', nothing should get across.
  13.523 + */
  13.524 +void __init cpu_init (void)
  13.525 +{
  13.526 +	int cpu = smp_processor_id();
  13.527 +	struct tss_struct * t = init_tss + cpu;
  13.528 +	struct thread_struct *thread = &current->thread;
  13.529 +
  13.530 +	if (test_and_set_bit(cpu, &cpu_initialized)) {
  13.531 +		printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
  13.532 +		for (;;) local_irq_enable();
  13.533 +	}
  13.534 +	printk(KERN_INFO "Initializing CPU#%d\n", cpu);
  13.535 +
  13.536 +	if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
  13.537 +		clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
  13.538 +	if (tsc_disable && cpu_has_tsc) {
  13.539 +		printk(KERN_NOTICE "Disabling TSC...\n");
  13.540 +		/**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
  13.541 +		clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
  13.542 +		set_in_cr4(X86_CR4_TSD);
  13.543 +	}
  13.544 +
  13.545 +	/*
  13.546 +	 * Initialize the per-CPU GDT with the boot GDT,
  13.547 +	 * and set up the GDT descriptor:
  13.548 +	 */
  13.549 +	if (cpu) {
  13.550 +		cpu_gdt_descr[cpu].size = GDT_SIZE;
  13.551 +		cpu_gdt_descr[cpu].address = 0;	/* XXXcl alloc page */
  13.552 +		BUG();		/* XXXcl SMP */
  13.553 +		memcpy((void *)cpu_gdt_descr[cpu].address,
  13.554 +		    (void *)cpu_gdt_descr[0].address, GDT_SIZE);
  13.555 +	}
  13.556 +	/*
  13.557 +	 * Set up the per-thread TLS descriptor cache:
  13.558 +	 */
  13.559 +	memcpy(thread->tls_array, &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN],
  13.560 +	    GDT_ENTRY_TLS_ENTRIES * 8);
  13.561 +
  13.562 +	cpu_gdt_init(&cpu_gdt_descr[cpu]);
  13.563 +
  13.564 +	/*
  13.565 +	 * Delete NT
  13.566 +	 */
  13.567 +	__asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
  13.568 +
  13.569 +	/*
  13.570 +	 * Set up and load the per-CPU TSS and LDT
  13.571 +	 */
  13.572 +	atomic_inc(&init_mm.mm_count);
  13.573 +	current->active_mm = &init_mm;
  13.574 +	if (current->mm)
  13.575 +		BUG();
  13.576 +	enter_lazy_tlb(&init_mm, current);
  13.577 +
  13.578 +	load_esp0(t, thread);
  13.579 +
  13.580 +	load_LDT(&init_mm.context);
  13.581 +	flush_page_update_queue();
  13.582 +
  13.583 +	/* Clear %fs and %gs. */
  13.584 +	asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
  13.585 +
  13.586 +	/* Clear all 6 debug registers: */
  13.587 +
  13.588 +#define CD(register) HYPERVISOR_set_debugreg(register, 0)
  13.589 +
  13.590 +	CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7);
  13.591 +
  13.592 +#undef CD
  13.593 +
  13.594 +	/*
  13.595 +	 * Force FPU initialization:
  13.596 +	 */
  13.597 +	current_thread_info()->status = 0;
  13.598 +	current->used_math = 0;
  13.599 +	mxcsr_feature_mask_init();
  13.600 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/entry.S	Wed Jul 14 16:41:41 2004 +0000
    14.3 @@ -0,0 +1,1030 @@
    14.4 +/*
    14.5 + *  linux/arch/i386/entry.S
    14.6 + *
    14.7 + *  Copyright (C) 1991, 1992  Linus Torvalds
    14.8 + */
    14.9 +
   14.10 +/*
   14.11 + * entry.S contains the system-call and fault low-level handling routines.
   14.12 + * This also contains the timer-interrupt handler, as well as all interrupts
   14.13 + * and faults that can result in a task-switch.
   14.14 + *
   14.15 + * NOTE: This code handles signal-recognition, which happens every time
   14.16 + * after a timer-interrupt and after each system call.
   14.17 + *
   14.18 + * I changed all the .align's to 4 (16 byte alignment), as that's faster
   14.19 + * on a 486.
   14.20 + *
   14.21 + * Stack layout in 'ret_from_system_call':
   14.22 + * 	ptrace needs to have all regs on the stack.
   14.23 + *	if the order here is changed, it needs to be
   14.24 + *	updated in fork.c:copy_process, signal.c:do_signal,
   14.25 + *	ptrace.c and ptrace.h
   14.26 + *
   14.27 + *	 0(%esp) - %ebx
   14.28 + *	 4(%esp) - %ecx
   14.29 + *	 8(%esp) - %edx
   14.30 + *       C(%esp) - %esi
   14.31 + *	10(%esp) - %edi
   14.32 + *	14(%esp) - %ebp
   14.33 + *	18(%esp) - %eax
   14.34 + *	1C(%esp) - %ds
   14.35 + *	20(%esp) - %es
   14.36 + *	24(%esp) - orig_eax
   14.37 + *	28(%esp) - %eip
   14.38 + *	2C(%esp) - %cs
   14.39 + *	30(%esp) - %eflags
   14.40 + *	34(%esp) - %oldesp
   14.41 + *	38(%esp) - %oldss
   14.42 + *
   14.43 + * "current" is in register %ebx during any slow entries.
   14.44 + */
   14.45 +
   14.46 +#include <linux/config.h>
   14.47 +#include <linux/linkage.h>
   14.48 +#include <asm/thread_info.h>
   14.49 +#include <asm/errno.h>
   14.50 +#include <asm/segment.h>
   14.51 +#include <asm/smp.h>
   14.52 +#include <asm/page.h>
   14.53 +#include "irq_vectors.h"
   14.54 +#include <asm/hypervisor-ifs/hypervisor-if.h>
   14.55 +
   14.56 +#define nr_syscalls ((syscall_table_size)/4)
   14.57 +
   14.58 +EBX		= 0x00
   14.59 +ECX		= 0x04
   14.60 +EDX		= 0x08
   14.61 +ESI		= 0x0C
   14.62 +EDI		= 0x10
   14.63 +EBP		= 0x14
   14.64 +EAX		= 0x18
   14.65 +DS		= 0x1C
   14.66 +ES		= 0x20
   14.67 +ORIG_EAX	= 0x24
   14.68 +EIP		= 0x28
   14.69 +CS		= 0x2C
   14.70 +EFLAGS		= 0x30
   14.71 +OLDESP		= 0x34
   14.72 +OLDSS		= 0x38
   14.73 +
   14.74 +CF_MASK		= 0x00000001
   14.75 +TF_MASK		= 0x00000100
   14.76 +IF_MASK		= 0x00000200
   14.77 +DF_MASK		= 0x00000400 
   14.78 +NT_MASK		= 0x00004000
   14.79 +VM_MASK		= 0x00020000
   14.80 +
   14.81 +/* Offsets into shared_info_t. */
   14.82 +#define evtchn_upcall_pending		/* 0 */
   14.83 +#define evtchn_upcall_mask		1
   14.84 +
   14.85 +#define XEN_BLOCK_EVENTS(reg)	movb $1,evtchn_upcall_mask(reg)
   14.86 +#define XEN_UNBLOCK_EVENTS(reg)	movb $0,evtchn_upcall_mask(reg)
   14.87 +#define XEN_TEST_PENDING(reg)	testb $0xFF,evtchn_upcall_pending(%reg)
   14.88 +
   14.89 +#ifdef CONFIG_PREEMPT
   14.90 +#define preempt_stop		movl HYPERVISOR_shared_info,%esi	; \
   14.91 +				XEN_BLOCK_EVENTS(%esi)
   14.92 +#else
   14.93 +#define preempt_stop
   14.94 +#define resume_kernel		restore_all
   14.95 +#endif
   14.96 +
   14.97 +#define SAVE_ALL \
   14.98 +	cld; \
   14.99 +	pushl %es; \
  14.100 +	pushl %ds; \
  14.101 +	pushl %eax; \
  14.102 +	pushl %ebp; \
  14.103 +	pushl %edi; \
  14.104 +	pushl %esi; \
  14.105 +	pushl %edx; \
  14.106 +	pushl %ecx; \
  14.107 +	pushl %ebx; \
  14.108 +	movl $(__KERNEL_DS), %edx; \
  14.109 +	movl %edx, %ds; \
  14.110 +	movl %edx, %es;
  14.111 +	# XXXcl USER?
  14.112 +
  14.113 +#define RESTORE_INT_REGS \
  14.114 +	popl %ebx;	\
  14.115 +	popl %ecx;	\
  14.116 +	popl %edx;	\
  14.117 +	popl %esi;	\
  14.118 +	popl %edi;	\
  14.119 +	popl %ebp;	\
  14.120 +	popl %eax
  14.121 +
  14.122 +#define RESTORE_REGS	\
  14.123 +	RESTORE_INT_REGS; \
  14.124 +1:	popl %ds;	\
  14.125 +2:	popl %es;	\
  14.126 +.section .fixup,"ax";	\
  14.127 +3:	movl $0,(%esp);	\
  14.128 +	jmp 1b;		\
  14.129 +4:	movl $0,(%esp);	\
  14.130 +	jmp 2b;		\
  14.131 +.previous;		\
  14.132 +.section __ex_table,"a";\
  14.133 +	.align 4;	\
  14.134 +	.long 1b,3b;	\
  14.135 +	.long 2b,4b;	\
  14.136 +.previous
  14.137 +
  14.138 +
  14.139 +#define RESTORE_ALL	\
  14.140 +	RESTORE_REGS	\
  14.141 +	addl $4, %esp;	\
  14.142 +1:	iret;		\
  14.143 +.section .fixup,"ax";   \
  14.144 +2:	movl $(__USER_DS), %edx; \
  14.145 +	movl %edx, %ds; \
  14.146 +	movl %edx, %es; \
  14.147 +	pushl $11;	\
  14.148 +	call do_exit;	\
  14.149 +.previous;		\
  14.150 +.section __ex_table,"a";\
  14.151 +	.align 4;	\
  14.152 +	.long 1b,2b;	\
  14.153 +.previous
  14.154 +
  14.155 +
  14.156 +
  14.157 +ENTRY(lcall7)
  14.158 +	pushfl			# We get a different stack layout with call
  14.159 +				# gates, which has to be cleaned up later..
  14.160 +	pushl %eax
  14.161 +	SAVE_ALL
  14.162 +	movl %esp, %ebp
  14.163 +	pushl %ebp
  14.164 +	pushl $0x7
  14.165 +do_lcall:
  14.166 +	movl EIP(%ebp), %eax	# due to call gates, this is eflags, not eip..
  14.167 +	movl CS(%ebp), %edx	# this is eip..
  14.168 +	movl EFLAGS(%ebp), %ecx	# and this is cs..
  14.169 +	movl %eax,EFLAGS(%ebp)	#
  14.170 +	movl %edx,EIP(%ebp)	# Now we move them to their "normal" places
  14.171 +	movl %ecx,CS(%ebp)	#
  14.172 +	GET_THREAD_INFO_WITH_ESP(%ebp)	# GET_THREAD_INFO
  14.173 +	movl TI_exec_domain(%ebp), %edx	# Get the execution domain
  14.174 +	call *EXEC_DOMAIN_handler(%edx)	# Call the handler for the domain
  14.175 +	addl $4, %esp
  14.176 +	popl %eax
  14.177 +	jmp resume_userspace
  14.178 +
  14.179 +ENTRY(lcall27)
  14.180 +	pushfl			# We get a different stack layout with call
  14.181 +				# gates, which has to be cleaned up later..
  14.182 +	pushl %eax
  14.183 +	SAVE_ALL
  14.184 +	movl %esp, %ebp
  14.185 +	pushl %ebp
  14.186 +	pushl $0x27
  14.187 +	jmp do_lcall
  14.188 +
  14.189 +
  14.190 +ENTRY(ret_from_fork)
  14.191 +	pushl %eax
  14.192 +	call schedule_tail
  14.193 +	GET_THREAD_INFO(%ebp)
  14.194 +	popl %eax
  14.195 +	jmp syscall_exit
  14.196 +
  14.197 +/*
  14.198 + * Return to user mode is not as complex as all this looks,
  14.199 + * but we want the default path for a system call return to
  14.200 + * go as quickly as possible which is why some of this is
  14.201 + * less clear than it otherwise should be.
  14.202 + */
  14.203 +
  14.204 +	# userspace resumption stub bypassing syscall exit tracing
  14.205 +	ALIGN
  14.206 +ret_from_exception:
  14.207 +	preempt_stop
  14.208 +ret_from_intr:
  14.209 +	GET_THREAD_INFO(%ebp)
  14.210 +	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
  14.211 +	movb CS(%esp), %al
  14.212 +	testl $(VM_MASK | 2), %eax
  14.213 +	jz resume_kernel		# returning to kernel or vm86-space
  14.214 +ENTRY(resume_userspace)
  14.215 +	movl HYPERVISOR_shared_info,%esi
  14.216 +	XEN_BLOCK_EVENTS(%esi)		# make tests atomic
  14.217 +					# make sure we don't miss an interrupt
  14.218 +					# setting need_resched or sigpending
  14.219 +					# between sampling and the iret
  14.220 +ret_syscall_tests:
  14.221 +	movl TI_flags(%ebp), %ecx
  14.222 +	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done on
  14.223 +					# int/exception return?
  14.224 +	jne work_pending
  14.225 +	jmp restore_all_enable_events
  14.226 +
  14.227 +#ifdef CONFIG_PREEMPT
  14.228 +ENTRY(resume_kernel)
  14.229 +	movl HYPERVISOR_shared_info,%esi
  14.230 +	cmpl $0,TI_preempt_count(%ebp)	# non-zero preempt_count ?
  14.231 +	jnz restore_all_enable_events
  14.232 +need_resched:
  14.233 +	movl TI_flags(%ebp), %ecx	# need_resched set ?
  14.234 +	testb $_TIF_NEED_RESCHED, %cl
  14.235 +	jz restore_all_enable_events
  14.236 +	testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
  14.237 +	jz restore_all_enable_events
  14.238 +	movl $PREEMPT_ACTIVE,TI_preempt_count(%ebp)
  14.239 +	XEN_UNBLOCK_EVENTS(%esi)	# reenable event callbacks
  14.240 +	call schedule
  14.241 +	movl $0,TI_preempt_count(%ebp)
  14.242 +	movl HYPERVISOR_shared_info,%esi
  14.243 +	XEN_BLOCK_EVENTS(%esi)		# make tests atomic
  14.244 +	jmp need_resched
  14.245 +#endif
  14.246 +
  14.247 +/* SYSENTER_RETURN points to after the "sysenter" instruction in
  14.248 +   the vsyscall page.  See vsyscall-sysentry.S, which defines the symbol.  */
  14.249 +
  14.250 +	# sysenter call handler stub
  14.251 +ENTRY(sysenter_entry)
  14.252 +	movl TSS_sysenter_esp0(%esp),%esp
  14.253 +sysenter_past_esp:
  14.254 +	sti
  14.255 +	pushl $(__USER_DS)
  14.256 +	pushl %ebp
  14.257 +	pushfl
  14.258 +	pushl $(__USER_CS)
  14.259 +	pushl $SYSENTER_RETURN
  14.260 +
  14.261 +/*
  14.262 + * Load the potential sixth argument from user stack.
  14.263 + * Careful about security.
  14.264 + */
  14.265 +	cmpl $__PAGE_OFFSET-3,%ebp
  14.266 +	jae syscall_fault
  14.267 +1:	movl (%ebp),%ebp
  14.268 +.section __ex_table,"a"
  14.269 +	.align 4
  14.270 +	.long 1b,syscall_fault
  14.271 +.previous
  14.272 +
  14.273 +	pushl %eax
  14.274 +	SAVE_ALL
  14.275 +	GET_THREAD_INFO(%ebp)
  14.276 +	cmpl $(nr_syscalls), %eax
  14.277 +	jae syscall_badsys
  14.278 +
  14.279 +	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
  14.280 +	jnz syscall_trace_entry
  14.281 +	call *sys_call_table(,%eax,4)
  14.282 +	movl %eax,EAX(%esp)
  14.283 +	cli
  14.284 +	movl TI_flags(%ebp), %ecx
  14.285 +	testw $_TIF_ALLWORK_MASK, %cx
  14.286 +	jne syscall_exit_work
  14.287 +/* if something modifies registers it must also disable sysexit */
  14.288 +	movl EIP(%esp), %edx
  14.289 +	movl OLDESP(%esp), %ecx
  14.290 +	sti
  14.291 +	sysexit
  14.292 +
  14.293 +
  14.294 +	# system call handler stub
  14.295 +ENTRY(system_call)
  14.296 +	pushl %eax			# save orig_eax
  14.297 +	SAVE_ALL
  14.298 +	GET_THREAD_INFO(%ebp)
  14.299 +	cmpl $(nr_syscalls), %eax
  14.300 +	jae syscall_badsys
  14.301 +					# system call tracing in operation
  14.302 +	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
  14.303 +	jnz syscall_trace_entry
  14.304 +syscall_call:
  14.305 +	call *sys_call_table(,%eax,4)
  14.306 +	movl %eax,EAX(%esp)		# store the return value
  14.307 +syscall_exit:
  14.308 +	movl HYPERVISOR_shared_info,%esi
  14.309 +	XEN_BLOCK_EVENTS(%esi)		# make tests atomic
  14.310 +					# make sure we don't miss an interrupt
  14.311 +					# setting need_resched or sigpending
  14.312 +					# between sampling and the iret
  14.313 +	movl TI_flags(%ebp), %ecx
  14.314 +	testw $_TIF_ALLWORK_MASK, %cx	# current->work
  14.315 +	jne syscall_exit_work
  14.316 +	jmp restore_all_enable_events
  14.317 +
  14.318 +	ALIGN
  14.319 +restore_all:
  14.320 +	RESTORE_ALL
  14.321 +
  14.322 +	# perform work that needs to be done immediately before resumption
  14.323 +	ALIGN
  14.324 +work_pending:
  14.325 +	XEN_UNBLOCK_EVENTS(%esi)	# reenable event callbacks
  14.326 +	testb $_TIF_NEED_RESCHED, %cl
  14.327 +	jz work_notifysig
  14.328 +work_resched:
  14.329 +	call schedule
  14.330 +	movl HYPERVISOR_shared_info,%esi
  14.331 +	XEN_BLOCK_EVENTS(%esi)		# make tests atomic
  14.332 +					# make sure we don't miss an interrupt
  14.333 +					# setting need_resched or sigpending
  14.334 +					# between sampling and the iret
  14.335 +	movl TI_flags(%ebp), %ecx
  14.336 +	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done other
  14.337 +					# than syscall tracing?
  14.338 +	jz restore_all_enable_events
  14.339 +	# XXXcl sti missing???
  14.340 +	XEN_UNBLOCK_EVENTS(%esi)	# reenable event callbacks
  14.341 +	testb $_TIF_NEED_RESCHED, %cl
  14.342 +	jnz work_resched
  14.343 +
  14.344 +work_notifysig:				# deal with pending signals and
  14.345 +					# notify-resume requests
  14.346 +	testl $VM_MASK, EFLAGS(%esp)
  14.347 +	movl %esp, %eax
  14.348 +	jne work_notifysig_v86		# returning to kernel-space or
  14.349 +					# vm86-space
  14.350 +	xorl %edx, %edx
  14.351 +	call do_notify_resume
  14.352 +	movl HYPERVISOR_shared_info,%esi
  14.353 +	jmp restore_all_enable_events
  14.354 +
  14.355 +	ALIGN
  14.356 +work_notifysig_v86:
  14.357 +	pushl %ecx
  14.358 +	call save_v86_state
  14.359 +	popl %ecx
  14.360 +	movl %eax, %esp
  14.361 +	xorl %edx, %edx
  14.362 +	call do_notify_resume
  14.363 +	movl HYPERVISOR_shared_info,%esi
  14.364 +	jmp restore_all_enable_events
  14.365 +
  14.366 +	# perform syscall exit tracing
  14.367 +	ALIGN
  14.368 +syscall_trace_entry:
  14.369 +	movl $-ENOSYS,EAX(%esp)
  14.370 +	movl %esp, %eax
  14.371 +	xorl %edx,%edx
  14.372 +	call do_syscall_trace
  14.373 +	movl ORIG_EAX(%esp), %eax
  14.374 +	cmpl $(nr_syscalls), %eax
  14.375 +	jnae syscall_call
  14.376 +	jmp syscall_exit
  14.377 +
  14.378 +	# perform syscall exit tracing
  14.379 +	ALIGN
  14.380 +syscall_exit_work:
  14.381 +	movl HYPERVISOR_shared_info,%esi
  14.382 +	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT), %cl
  14.383 +	jz work_pending
  14.384 +	XEN_UNBLOCK_EVENTS(%esi)	# reenable event callbacks
  14.385 +					# could let do_syscall_trace() call
  14.386 +					# schedule() instead
  14.387 +	movl %esp, %eax
  14.388 +	movl $1, %edx
  14.389 +	call do_syscall_trace
  14.390 +	jmp resume_userspace
  14.391 +
  14.392 +	ALIGN
  14.393 +syscall_fault:
  14.394 +	pushl %eax			# save orig_eax
  14.395 +	SAVE_ALL
  14.396 +	GET_THREAD_INFO(%ebp)
  14.397 +	movl $-EFAULT,EAX(%esp)
  14.398 +	jmp resume_userspace
  14.399 +
  14.400 +	ALIGN
  14.401 +syscall_badsys:
  14.402 +	movl $-ENOSYS,EAX(%esp)
  14.403 +	jmp resume_userspace
  14.404 +
  14.405 +ENTRY(divide_error)
  14.406 +	pushl $0			# no error code
  14.407 +	pushl $do_divide_error
  14.408 +	ALIGN
  14.409 +error_code:
  14.410 +	pushl %ds
  14.411 +	pushl %eax
  14.412 +	xorl %eax, %eax
  14.413 +	pushl %ebp
  14.414 +	pushl %edi
  14.415 +	pushl %esi
  14.416 +	pushl %edx
  14.417 +	decl %eax			# eax = -1
  14.418 +	pushl %ecx
  14.419 +	pushl %ebx
  14.420 +	cld
  14.421 +	movl %es, %ecx
  14.422 +	movl ORIG_EAX(%esp), %esi	# get the error code
  14.423 +	movl ES(%esp), %edi		# get the function address
  14.424 +	movl %eax, ORIG_EAX(%esp)
  14.425 +	movl %ecx, ES(%esp)
  14.426 +	movl %esp, %edx
  14.427 +	pushl %esi			# push the error code
  14.428 +	pushl %edx			# push the pt_regs pointer
  14.429 +	movl $(__KERNEL_DS), %edx	# XXXcl USER?
  14.430 +	movl %edx, %ds
  14.431 +	movl %edx, %es
  14.432 +	call *%edi
  14.433 +	addl $8, %esp
  14.434 +	jmp ret_from_exception
  14.435 +
  14.436 +# A note on the "critical region" in our callback handler.
  14.437 +# We want to avoid stacking callback handlers due to events occurring
  14.438 +# during handling of the last event. To do this, we keep events disabled
  14.439 +# until we've done all processing. HOWEVER, we must enable events before
  14.440 +# popping the stack frame (can't be done atomically) and so it would still
  14.441 +# be possible to get enough handler activations to overflow the stack.
  14.442 +# Although unlikely, bugs of that kind are hard to track down, so we'd
  14.443 +# like to avoid the possibility.
  14.444 +# So, on entry to the handler we detect whether we interrupted an
  14.445 +# existing activation in its critical region -- if so, we pop the current
  14.446 +# activation and restart the handler using the previous one.
  14.447 +ENTRY(hypervisor_callback)
  14.448 +	pushl %eax
  14.449 +	SAVE_ALL
  14.450 +	GET_THREAD_INFO(%ebp)
  14.451 +	movl EIP(%esp),%eax
  14.452 +	cmpl $scrit,%eax
  14.453 +	jb   11f
  14.454 +	cmpl $ecrit,%eax
  14.455 +	jb   critical_region_fixup
  14.456 +11:	push %esp
  14.457 +	call evtchn_do_upcall
  14.458 +	add  $4,%esp
  14.459 +	movl HYPERVISOR_shared_info,%esi
  14.460 +	movb CS(%esp),%cl
  14.461 +	test $2,%cl			# slow return to ring 2 or 3
  14.462 +	jne  ret_syscall_tests
  14.463 +restore_all_enable_events:  
  14.464 +safesti:XEN_UNBLOCK_EVENTS(%esi)	# reenable event callbacks
  14.465 +scrit:	/**** START OF CRITICAL REGION ****/
  14.466 +	testb $1,evtchn_upcall_pending(%esi)
  14.467 +	jnz  14f			# process more events if necessary...
  14.468 +	RESTORE_ALL
  14.469 +14:	XEN_BLOCK_EVENTS(%esi)
  14.470 +	jmp  11b
  14.471 +ecrit:  /**** END OF CRITICAL REGION ****/
  14.472 +# [How we do the fixup]. We want to merge the current stack frame with the
  14.473 +# just-interrupted frame. How we do this depends on where in the critical
  14.474 +# region the interrupted handler was executing, and so how many saved
  14.475 +# registers are in each frame. We do this quickly using the lookup table
  14.476 +# 'critical_fixup_table'. For each byte offset in the critical region, it
  14.477 +# provides the number of bytes which have already been popped from the
  14.478 +# interrupted stack frame. 
  14.479 +critical_region_fixup:
  14.480 +	addl $critical_fixup_table-scrit,%eax
  14.481 +	movzbl (%eax),%eax		# %eax contains num bytes popped
  14.482 +	mov  %esp,%esi
  14.483 +	add  %eax,%esi			# %esi points at end of src region
  14.484 +	mov  %esp,%edi
  14.485 +	add  $0x34,%edi			# %edi points at end of dst region
  14.486 +	mov  %eax,%ecx
  14.487 +	shr  $2,%ecx			# convert words to bytes
  14.488 +	je   16f			# skip loop if nothing to copy
  14.489 +15:	subl $4,%esi			# pre-decrementing copy loop
  14.490 +	subl $4,%edi
  14.491 +	movl (%esi),%eax
  14.492 +	movl %eax,(%edi)
  14.493 +	loop 15b
  14.494 +16:	movl %edi,%esp			# final %edi is top of merged stack
  14.495 +	jmp  11b
  14.496 +
  14.497 +critical_fixup_table:
  14.498 +	.byte 0x00,0x00,0x00		# testb $0xff,(%esi)
  14.499 +	.byte 0x00,0x00			# jnz  14f
  14.500 +	.byte 0x00			# pop  %ebx
  14.501 +	.byte 0x04			# pop  %ecx
  14.502 +	.byte 0x08			# pop  %edx
  14.503 +	.byte 0x0c			# pop  %esi
  14.504 +	.byte 0x10			# pop  %edi
  14.505 +	.byte 0x14			# pop  %ebp
  14.506 +	.byte 0x18			# pop  %eax
  14.507 +	.byte 0x1c			# pop  %ds
  14.508 +	.byte 0x20			# pop  %es
  14.509 +	.byte 0x24,0x24,0x24		# add  $4,%esp
  14.510 +	.byte 0x28			# iret
  14.511 +	.byte 0x00,0x00,0x00,0x00	# movb $1,1(%esi)
  14.512 +	.byte 0x00,0x00			# jmp  11b
  14.513 +
  14.514 +# Hypervisor uses this for application faults while it executes.
  14.515 +ENTRY(failsafe_callback)
  14.516 +	pushal
  14.517 +	call install_safe_pf_handler
  14.518 +	movl 32(%esp),%ebx
  14.519 +1:	movl %ebx,%ds
  14.520 +	movl 36(%esp),%ebx
  14.521 +2:	movl %ebx,%es
  14.522 +	movl 40(%esp),%ebx
  14.523 +3:	movl %ebx,%fs
  14.524 +	movl 44(%esp),%ebx
  14.525 +4:	movl %ebx,%gs
  14.526 +	call install_normal_pf_handler
  14.527 +	popal
  14.528 +	addl $16,%esp
  14.529 +5:	iret
  14.530 +.section .fixup,"ax";	\
  14.531 +6:	xorl %ebx,%ebx;	\
  14.532 +	jmp 1b;		\
  14.533 +7:	xorl %ebx,%ebx;	\
  14.534 +	jmp 2b;		\
  14.535 +8:	xorl %ebx,%ebx;	\
  14.536 +	jmp 3b;		\
  14.537 +9:	xorl %ebx,%ebx;	\
  14.538 +	jmp 4b;		\
  14.539 +10:	pushl %ss;	\
  14.540 +	popl %ds;	\
  14.541 +	pushl %ss;	\
  14.542 +	popl %es;	\
  14.543 +	pushl $11;	\
  14.544 +	call do_exit;	\
  14.545 +.previous;		\
  14.546 +.section __ex_table,"a";\
  14.547 +	.align 4;	\
  14.548 +	.long 1b,6b;	\
  14.549 +	.long 2b,7b;	\
  14.550 +	.long 3b,8b;	\
  14.551 +	.long 4b,9b;	\
  14.552 +	.long 5b,10b;	\
  14.553 +.previous
  14.554 +
  14.555 +ENTRY(coprocessor_error)
  14.556 +	pushl $0
  14.557 +	pushl $do_coprocessor_error
  14.558 +	jmp error_code
  14.559 +
  14.560 +ENTRY(simd_coprocessor_error)
  14.561 +	pushl $0
  14.562 +	pushl $do_simd_coprocessor_error
  14.563 +	jmp error_code
  14.564 +
  14.565 +ENTRY(device_not_available)
  14.566 +	pushl $-1			# mark this as an int
  14.567 +	SAVE_ALL
  14.568 +	preempt_stop
  14.569 +	call math_state_restore
  14.570 +	jmp ret_from_exception
  14.571 +
  14.572 +/*
  14.573 + * Debug traps and NMI can happen at the one SYSENTER instruction
  14.574 + * that sets up the real kernel stack. Check here, since we can't
  14.575 + * allow the wrong stack to be used.
  14.576 + *
  14.577 + * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
  14.578 + * already pushed 3 words if it hits on the sysenter instruction:
  14.579 + * eflags, cs and eip.
  14.580 + *
  14.581 + * We just load the right stack, and push the three (known) values
  14.582 + * by hand onto the new stack - while updating the return eip past
  14.583 + * the instruction that would have done it for sysenter.
  14.584 + */
  14.585 +#define FIX_STACK(offset, ok, label)		\
  14.586 +	cmpw $__KERNEL_CS,4(%esp);		\
  14.587 +	jne ok;					\
  14.588 +label:						\
  14.589 +	movl TSS_sysenter_esp0+offset(%esp),%esp;	\
  14.590 +	pushfl;					\
  14.591 +	pushl $__KERNEL_CS;			\
  14.592 +	pushl $sysenter_past_esp
  14.593 +
  14.594 +ENTRY(debug)
  14.595 +	cmpl $sysenter_entry,(%esp)
  14.596 +	jne debug_stack_correct
  14.597 +	FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
  14.598 +debug_stack_correct:
  14.599 +	pushl $0
  14.600 +	pushl $do_debug
  14.601 +	jmp error_code
  14.602 +
  14.603 +#if 0
  14.604 +/*
  14.605 + * NMI is doubly nasty. It can happen _while_ we're handling
  14.606 + * a debug fault, and the debug fault hasn't yet been able to
  14.607 + * clear up the stack. So we first check whether we got  an
  14.608 + * NMI on the sysenter entry path, but after that we need to
  14.609 + * check whether we got an NMI on the debug path where the debug
  14.610 + * fault happened on the sysenter path.
  14.611 + */
  14.612 +ENTRY(nmi)
  14.613 +	cmpl $sysenter_entry,(%esp)
  14.614 +	je nmi_stack_fixup
  14.615 +	pushl %eax
  14.616 +	movl %esp,%eax
  14.617 +	/* Do not access memory above the end of our stack page,
  14.618 +	 * it might not exist.
  14.619 +	 */
  14.620 +	andl $(THREAD_SIZE-1),%eax
  14.621 +	cmpl $(THREAD_SIZE-20),%eax
  14.622 +	popl %eax
  14.623 +	jae nmi_stack_correct
  14.624 +	cmpl $sysenter_entry,12(%esp)
  14.625 +	je nmi_debug_stack_check
  14.626 +nmi_stack_correct:
  14.627 +	pushl %eax
  14.628 +	SAVE_ALL
  14.629 +	movl %esp, %edx
  14.630 +	pushl $0
  14.631 +	pushl %edx
  14.632 +	call do_nmi
  14.633 +	addl $8, %esp
  14.634 +	RESTORE_ALL
  14.635 +
  14.636 +nmi_stack_fixup:
  14.637 +	FIX_STACK(12,nmi_stack_correct, 1)
  14.638 +	jmp nmi_stack_correct
  14.639 +nmi_debug_stack_check:
  14.640 +	cmpw $__KERNEL_CS,16(%esp)
  14.641 +	jne nmi_stack_correct
  14.642 +	cmpl $debug - 1,(%esp)
  14.643 +	jle nmi_stack_correct
  14.644 +	cmpl $debug_esp_fix_insn,(%esp)
  14.645 +	jle nmi_debug_stack_fixup
  14.646 +nmi_debug_stack_fixup:
  14.647 +	FIX_STACK(24,nmi_stack_correct, 1)
  14.648 +	jmp nmi_stack_correct
  14.649 +#endif
  14.650 +
  14.651 +ENTRY(int3)
  14.652 +	pushl $0
  14.653 +	pushl $do_int3
  14.654 +	jmp error_code
  14.655 +
  14.656 +ENTRY(overflow)
  14.657 +	pushl $0
  14.658 +	pushl $do_overflow
  14.659 +	jmp error_code
  14.660 +
  14.661 +ENTRY(bounds)
  14.662 +	pushl $0
  14.663 +	pushl $do_bounds
  14.664 +	jmp error_code
  14.665 +
  14.666 +ENTRY(invalid_op)
  14.667 +	pushl $0
  14.668 +	pushl $do_invalid_op
  14.669 +	jmp error_code
  14.670 +
  14.671 +ENTRY(coprocessor_segment_overrun)
  14.672 +	pushl $0
  14.673 +	pushl $do_coprocessor_segment_overrun
  14.674 +	jmp error_code
  14.675 +
  14.676 +ENTRY(double_fault)
  14.677 +	pushl $do_double_fault
  14.678 +	jmp error_code
  14.679 +
  14.680 +ENTRY(invalid_TSS)
  14.681 +	pushl $do_invalid_TSS
  14.682 +	jmp error_code
  14.683 +
  14.684 +ENTRY(segment_not_present)
  14.685 +	pushl $do_segment_not_present
  14.686 +	jmp error_code
  14.687 +
  14.688 +ENTRY(stack_segment)
  14.689 +	pushl $do_stack_segment
  14.690 +	jmp error_code
  14.691 +
  14.692 +ENTRY(general_protection)
  14.693 +	pushl $do_general_protection
  14.694 +	jmp error_code
  14.695 +
  14.696 +ENTRY(alignment_check)
  14.697 +	pushl $do_alignment_check
  14.698 +	jmp error_code
  14.699 +
  14.700 +# This handler is special, because it gets an extra value on its stack,
  14.701 +# which is the linear faulting address.
  14.702 +#define PAGE_FAULT_STUB(_name1, _name2)					  \
  14.703 +ENTRY(_name1)								  \
  14.704 +	pushl %ds							; \
  14.705 +	pushl %eax							; \
  14.706 +	xorl %eax,%eax							; \
  14.707 +	pushl %ebp							; \
  14.708 +	pushl %edi							; \
  14.709 +	pushl %esi							; \
  14.710 +	pushl %edx							; \
  14.711 +	decl %eax			/* eax = -1 */			; \
  14.712 +	pushl %ecx							; \
  14.713 +	pushl %ebx							; \
  14.714 +	GET_THREAD_INFO(%ebp)						; \
  14.715 +	cld								; \
  14.716 +	movl %es,%ecx							; \
  14.717 +	movl ORIG_EAX(%esp), %esi	/* get the error code */	; \
  14.718 +	movl ES(%esp), %edi		/* get the faulting address */	; \
  14.719 +	movl %eax, ORIG_EAX(%esp)					; \
  14.720 +	movl %ecx, ES(%esp)						; \
  14.721 +	movl %esp,%edx							; \
  14.722 +	pushl %edi			/* push the faulting address */	; \
  14.723 +	pushl %esi			/* push the error code */	; \
  14.724 +	pushl %edx			/* push the pt_regs pointer */	; \
  14.725 +	movl $(__KERNEL_DS),%edx					; \
  14.726 +	movl %edx,%ds							; \
  14.727 +	movl %edx,%es							; \
  14.728 +	call _name2							; \
  14.729 +	addl $12,%esp							; \
  14.730 +	jmp ret_from_exception						;
  14.731 +PAGE_FAULT_STUB(page_fault, do_page_fault)
  14.732 +PAGE_FAULT_STUB(safe_page_fault, do_safe_page_fault)
  14.733 +
  14.734 +#ifdef CONFIG_X86_MCE
  14.735 +ENTRY(machine_check)
  14.736 +	pushl $0
  14.737 +	pushl machine_check_vector
  14.738 +	jmp error_code
  14.739 +#endif
  14.740 +
  14.741 +ENTRY(spurious_interrupt_bug)
  14.742 +	pushl $0
  14.743 +	pushl $do_spurious_interrupt_bug
  14.744 +	jmp error_code
  14.745 +
  14.746 +.data
  14.747 +ENTRY(sys_call_table)
  14.748 +	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
  14.749 +	.long sys_exit
  14.750 +	.long sys_fork
  14.751 +	.long sys_read
  14.752 +	.long sys_write
  14.753 +	.long sys_open		/* 5 */
  14.754 +	.long sys_close
  14.755 +	.long sys_waitpid
  14.756 +	.long sys_creat
  14.757 +	.long sys_link
  14.758 +	.long sys_unlink	/* 10 */
  14.759 +	.long sys_execve
  14.760 +	.long sys_chdir
  14.761 +	.long sys_time
  14.762 +	.long sys_mknod
  14.763 +	.long sys_chmod		/* 15 */
  14.764 +	.long sys_lchown16
  14.765 +	.long sys_ni_syscall	/* old break syscall holder */
  14.766 +	.long sys_stat
  14.767 +	.long sys_lseek
  14.768 +	.long sys_getpid	/* 20 */
  14.769 +	.long sys_mount
  14.770 +	.long sys_oldumount
  14.771 +	.long sys_setuid16
  14.772 +	.long sys_getuid16
  14.773 +	.long sys_stime		/* 25 */
  14.774 +	.long sys_ptrace
  14.775 +	.long sys_alarm
  14.776 +	.long sys_fstat
  14.777 +	.long sys_pause
  14.778 +	.long sys_utime		/* 30 */
  14.779 +	.long sys_ni_syscall	/* old stty syscall holder */
  14.780 +	.long sys_ni_syscall	/* old gtty syscall holder */
  14.781 +	.long sys_access
  14.782 +	.long sys_nice
  14.783 +	.long sys_ni_syscall	/* 35 - old ftime syscall holder */
  14.784 +	.long sys_sync
  14.785 +	.long sys_kill
  14.786 +	.long sys_rename
  14.787 +	.long sys_mkdir
  14.788 +	.long sys_rmdir		/* 40 */
  14.789 +	.long sys_dup
  14.790 +	.long sys_pipe
  14.791 +	.long sys_times
  14.792 +	.long sys_ni_syscall	/* old prof syscall holder */
  14.793 +	.long sys_brk		/* 45 */
  14.794 +	.long sys_setgid16
  14.795 +	.long sys_getgid16
  14.796 +	.long sys_signal
  14.797 +	.long sys_geteuid16
  14.798 +	.long sys_getegid16	/* 50 */
  14.799 +	.long sys_acct
  14.800 +	.long sys_umount	/* recycled never used phys() */
  14.801 +	.long sys_ni_syscall	/* old lock syscall holder */
  14.802 +	.long sys_ioctl
  14.803 +	.long sys_fcntl		/* 55 */
  14.804 +	.long sys_ni_syscall	/* old mpx syscall holder */
  14.805 +	.long sys_setpgid
  14.806 +	.long sys_ni_syscall	/* old ulimit syscall holder */
  14.807 +	.long sys_olduname
  14.808 +	.long sys_umask		/* 60 */
  14.809 +	.long sys_chroot
  14.810 +	.long sys_ustat
  14.811 +	.long sys_dup2
  14.812 +	.long sys_getppid
  14.813 +	.long sys_getpgrp	/* 65 */
  14.814 +	.long sys_setsid
  14.815 +	.long sys_sigaction
  14.816 +	.long sys_sgetmask
  14.817 +	.long sys_ssetmask
  14.818 +	.long sys_setreuid16	/* 70 */
  14.819 +	.long sys_setregid16
  14.820 +	.long sys_sigsuspend
  14.821 +	.long sys_sigpending
  14.822 +	.long sys_sethostname
  14.823 +	.long sys_setrlimit	/* 75 */
  14.824 +	.long sys_old_getrlimit
  14.825 +	.long sys_getrusage
  14.826 +	.long sys_gettimeofday
  14.827 +	.long sys_settimeofday
  14.828 +	.long sys_getgroups16	/* 80 */
  14.829 +	.long sys_setgroups16
  14.830 +	.long old_select
  14.831 +	.long sys_symlink
  14.832 +	.long sys_lstat
  14.833 +	.long sys_readlink	/* 85 */
  14.834 +	.long sys_uselib
  14.835 +	.long sys_swapon
  14.836 +	.long sys_reboot
  14.837 +	.long old_readdir
  14.838 +	.long old_mmap		/* 90 */
  14.839 +	.long sys_munmap
  14.840 +	.long sys_truncate
  14.841 +	.long sys_ftruncate
  14.842 +	.long sys_fchmod
  14.843 +	.long sys_fchown16	/* 95 */
  14.844 +	.long sys_getpriority
  14.845 +	.long sys_setpriority
  14.846 +	.long sys_ni_syscall	/* old profil syscall holder */
  14.847 +	.long sys_statfs
  14.848 +	.long sys_fstatfs	/* 100 */
  14.849 +	.long sys_ioperm
  14.850 +	.long sys_socketcall
  14.851 +	.long sys_syslog
  14.852 +	.long sys_setitimer
  14.853 +	.long sys_getitimer	/* 105 */
  14.854 +	.long sys_newstat
  14.855 +	.long sys_newlstat
  14.856 +	.long sys_newfstat
  14.857 +	.long sys_uname
  14.858 +	.long sys_iopl		/* 110 */
  14.859 +	.long sys_vhangup
  14.860 +	.long sys_ni_syscall	/* old "idle" system call */
  14.861 +	.long sys_vm86old
  14.862 +	.long sys_wait4
  14.863 +	.long sys_swapoff	/* 115 */
  14.864 +	.long sys_sysinfo
  14.865 +	.long sys_ipc
  14.866 +	.long sys_fsync
  14.867 +	.long sys_sigreturn
  14.868 +	.long sys_clone		/* 120 */
  14.869 +	.long sys_setdomainname
  14.870 +	.long sys_newuname
  14.871 +	.long sys_modify_ldt
  14.872 +	.long sys_adjtimex
  14.873 +	.long sys_mprotect	/* 125 */
  14.874 +	.long sys_sigprocmask
  14.875 +	.long sys_ni_syscall	/* old "create_module" */ 
  14.876 +	.long sys_init_module
  14.877 +	.long sys_delete_module
  14.878 +	.long sys_ni_syscall	/* 130:	old "get_kernel_syms" */
  14.879 +	.long sys_quotactl
  14.880 +	.long sys_getpgid
  14.881 +	.long sys_fchdir
  14.882 +	.long sys_bdflush
  14.883 +	.long sys_sysfs		/* 135 */
  14.884 +	.long sys_personality
  14.885 +	.long sys_ni_syscall	/* reserved for afs_syscall */
  14.886 +	.long sys_setfsuid16
  14.887 +	.long sys_setfsgid16
  14.888 +	.long sys_llseek	/* 140 */
  14.889 +	.long sys_getdents
  14.890 +	.long sys_select
  14.891 +	.long sys_flock
  14.892 +	.long sys_msync
  14.893 +	.long sys_readv		/* 145 */
  14.894 +	.long sys_writev
  14.895 +	.long sys_getsid
  14.896 +	.long sys_fdatasync
  14.897 +	.long sys_sysctl
  14.898 +	.long sys_mlock		/* 150 */
  14.899 +	.long sys_munlock
  14.900 +	.long sys_mlockall
  14.901 +	.long sys_munlockall
  14.902 +	.long sys_sched_setparam
  14.903 +	.long sys_sched_getparam   /* 155 */
  14.904 +	.long sys_sched_setscheduler
  14.905 +	.long sys_sched_getscheduler
  14.906 +	.long sys_sched_yield
  14.907 +	.long sys_sched_get_priority_max
  14.908 +	.long sys_sched_get_priority_min  /* 160 */
  14.909 +	.long sys_sched_rr_get_interval
  14.910 +	.long sys_nanosleep
  14.911 +	.long sys_mremap
  14.912 +	.long sys_setresuid16
  14.913 +	.long sys_getresuid16	/* 165 */
  14.914 +	.long sys_vm86
  14.915 +	.long sys_ni_syscall	/* Old sys_query_module */
  14.916 +	.long sys_poll
  14.917 +	.long sys_nfsservctl
  14.918 +	.long sys_setresgid16	/* 170 */
  14.919 +	.long sys_getresgid16
  14.920 +	.long sys_prctl
  14.921 +	.long sys_rt_sigreturn
  14.922 +	.long sys_rt_sigaction
  14.923 +	.long sys_rt_sigprocmask	/* 175 */
  14.924 +	.long sys_rt_sigpending
  14.925 +	.long sys_rt_sigtimedwait
  14.926 +	.long sys_rt_sigqueueinfo
  14.927 +	.long sys_rt_sigsuspend
  14.928 +	.long sys_pread64	/* 180 */
  14.929 +	.long sys_pwrite64
  14.930 +	.long sys_chown16
  14.931 +	.long sys_getcwd
  14.932 +	.long sys_capget
  14.933 +	.long sys_capset	/* 185 */
  14.934 +	.long sys_sigaltstack
  14.935 +	.long sys_sendfile
  14.936 +	.long sys_ni_syscall	/* reserved for streams1 */
  14.937 +	.long sys_ni_syscall	/* reserved for streams2 */
  14.938 +	.long sys_vfork		/* 190 */
  14.939 +	.long sys_getrlimit
  14.940 +	.long sys_mmap2
  14.941 +	.long sys_truncate64
  14.942 +	.long sys_ftruncate64
  14.943 +	.long sys_stat64	/* 195 */
  14.944 +	.long sys_lstat64
  14.945 +	.long sys_fstat64
  14.946 +	.long sys_lchown
  14.947 +	.long sys_getuid
  14.948 +	.long sys_getgid	/* 200 */
  14.949 +	.long sys_geteuid
  14.950 +	.long sys_getegid
  14.951 +	.long sys_setreuid
  14.952 +	.long sys_setregid
  14.953 +	.long sys_getgroups	/* 205 */
  14.954 +	.long sys_setgroups
  14.955 +	.long sys_fchown
  14.956 +	.long sys_setresuid
  14.957 +	.long sys_getresuid
  14.958 +	.long sys_setresgid	/* 210 */
  14.959 +	.long sys_getresgid
  14.960 +	.long sys_chown
  14.961 +	.long sys_setuid
  14.962 +	.long sys_setgid
  14.963 +	.long sys_setfsuid	/* 215 */
  14.964 +	.long sys_setfsgid
  14.965 +	.long sys_pivot_root
  14.966 +	.long sys_mincore
  14.967 +	.long sys_madvise
  14.968 +	.long sys_getdents64	/* 220 */
  14.969 +	.long sys_fcntl64
  14.970 +	.long sys_ni_syscall	/* reserved for TUX */
  14.971 +	.long sys_ni_syscall
  14.972 +	.long sys_gettid
  14.973 +	.long sys_readahead	/* 225 */
  14.974 +	.long sys_setxattr
  14.975 +	.long sys_lsetxattr
  14.976 +	.long sys_fsetxattr
  14.977 +	.long sys_getxattr
  14.978 +	.long sys_lgetxattr	/* 230 */
  14.979 +	.long sys_fgetxattr
  14.980 +	.long sys_listxattr
  14.981 +	.long sys_llistxattr
  14.982 +	.long sys_flistxattr
  14.983 +	.long sys_removexattr	/* 235 */
  14.984 +	.long sys_lremovexattr
  14.985 +	.long sys_fremovexattr
  14.986 +	.long sys_tkill
  14.987 +	.long sys_sendfile64
  14.988 +	.long sys_futex		/* 240 */
  14.989 +	.long sys_sched_setaffinity
  14.990 +	.long sys_sched_getaffinity
  14.991 +	.long sys_set_thread_area
  14.992 +	.long sys_get_thread_area
  14.993 +	.long sys_io_setup	/* 245 */
  14.994 +	.long sys_io_destroy
  14.995 +	.long sys_io_getevents
  14.996 +	.long sys_io_submit
  14.997 +	.long sys_io_cancel
  14.998 +	.long sys_fadvise64	/* 250 */
  14.999 +	.long sys_ni_syscall
 14.1000 +	.long sys_exit_group
 14.1001 +	.long sys_lookup_dcookie
 14.1002 +	.long sys_epoll_create
 14.1003 +	.long sys_epoll_ctl	/* 255 */
 14.1004 +	.long sys_epoll_wait
 14.1005 + 	.long sys_remap_file_pages
 14.1006 + 	.long sys_set_tid_address
 14.1007 + 	.long sys_timer_create
 14.1008 + 	.long sys_timer_settime		/* 260 */
 14.1009 + 	.long sys_timer_gettime
 14.1010 + 	.long sys_timer_getoverrun
 14.1011 + 	.long sys_timer_delete
 14.1012 + 	.long sys_clock_settime
 14.1013 + 	.long sys_clock_gettime		/* 265 */
 14.1014 + 	.long sys_clock_getres
 14.1015 + 	.long sys_clock_nanosleep
 14.1016 +	.long sys_statfs64
 14.1017 +	.long sys_fstatfs64	
 14.1018 +	.long sys_tgkill	/* 270 */
 14.1019 +	.long sys_utimes
 14.1020 + 	.long sys_fadvise64_64
 14.1021 +	.long sys_ni_syscall	/* sys_vserver */
 14.1022 +	.long sys_mbind
 14.1023 +	.long sys_get_mempolicy
 14.1024 +	.long sys_set_mempolicy
 14.1025 +	.long sys_mq_open
 14.1026 +	.long sys_mq_unlink
 14.1027 +	.long sys_mq_timedsend
 14.1028 +	.long sys_mq_timedreceive	/* 280 */
 14.1029 +	.long sys_mq_notify
 14.1030 +	.long sys_mq_getsetattr
 14.1031 +	.long sys_ni_syscall		/* reserved for kexec */
 14.1032 +
 14.1033 +syscall_table_size=(.-sys_call_table)
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/evtchn.c	Wed Jul 14 16:41:41 2004 +0000
    15.3 @@ -0,0 +1,479 @@
    15.4 +/******************************************************************************
    15.5 + * evtchn.c
    15.6 + * 
    15.7 + * Communication via Xen event channels.
    15.8 + * 
    15.9 + * Copyright (c) 2002-2004, K A Fraser
   15.10 + */
   15.11 +
   15.12 +#include <linux/config.h>
   15.13 +#include <linux/irq.h>
   15.14 +#include <linux/interrupt.h>
   15.15 +#include <linux/sched.h>
   15.16 +#include <linux/kernel_stat.h>
   15.17 +#include <asm/atomic.h>
   15.18 +#include <asm/system.h>
   15.19 +#include <asm/ptrace.h>
   15.20 +#include <asm/synch_bitops.h>
   15.21 +#include <asm/hypervisor.h>
   15.22 +#include <asm/hypervisor-ifs/event_channel.h>
   15.23 +#include <asm/hypervisor-ifs/physdev.h>
   15.24 +#include <asm-xen/ctrl_if.h>
   15.25 +
   15.26 +/*
   15.27 + * This lock protects updates to the following mapping and reference-count
   15.28 + * arrays. The lock does not need to be acquired to read the mapping tables.
   15.29 + */
   15.30 +static spinlock_t irq_mapping_update_lock;
   15.31 +
   15.32 +/* IRQ <-> event-channel mappings. */
   15.33 +static int evtchn_to_irq[NR_EVENT_CHANNELS];
   15.34 +static int irq_to_evtchn[NR_IRQS];
   15.35 +
   15.36 +/* IRQ <-> VIRQ mapping. */
   15.37 +static int virq_to_irq[NR_VIRQS];
   15.38 +
   15.39 +/* Reference counts for bindings to IRQs. */
   15.40 +static int irq_bindcount[NR_IRQS];
   15.41 +
   15.42 +/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
   15.43 +static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)];
   15.44 +
   15.45 +/* Upcall to generic IRQ layer. */
   15.46 +extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
   15.47 +
   15.48 +#define VALID_EVTCHN(_chn) ((_chn) != -1)
   15.49 +
   15.50 +void evtchn_do_upcall(struct pt_regs *regs)
   15.51 +{
   15.52 +    unsigned long  l1, l2;
   15.53 +    unsigned int   l1i, l2i, port;
   15.54 +    int            irq;
   15.55 +    unsigned long  flags;
   15.56 +    shared_info_t *s = HYPERVISOR_shared_info;
   15.57 +
   15.58 +    local_irq_save(flags);
   15.59 +    
   15.60 +    while ( s->vcpu_data[0].evtchn_upcall_pending )
   15.61 +    {
   15.62 +        s->vcpu_data[0].evtchn_upcall_pending = 0;
   15.63 +        /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
   15.64 +        l1 = xchg(&s->evtchn_pending_sel, 0);
   15.65 +        while ( (l1i = ffs(l1)) != 0 )
   15.66 +        {
   15.67 +            l1i--;
   15.68 +            l1 &= ~(1 << l1i);
   15.69 +        
   15.70 +            l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
   15.71 +            while ( (l2i = ffs(l2)) != 0 )
   15.72 +            {
   15.73 +                l2i--;
   15.74 +                l2 &= ~(1 << l2i);
   15.75 +            
   15.76 +                port = (l1i << 5) + l2i;
   15.77 +                if ( (irq = evtchn_to_irq[port]) != -1 )
   15.78 +                    do_IRQ(irq, regs);
   15.79 +                else
   15.80 +                    evtchn_device_upcall(port);
   15.81 +            }
   15.82 +        }
   15.83 +    }
   15.84 +
   15.85 +    local_irq_restore(flags);
   15.86 +}
   15.87 +
   15.88 +
   15.89 +static int find_unbound_irq(void)
   15.90 +{
   15.91 +    int irq;
   15.92 +
   15.93 +    for ( irq = 0; irq < NR_IRQS; irq++ )
   15.94 +        if ( irq_bindcount[irq] == 0 )
   15.95 +            break;
   15.96 +
   15.97 +    if ( irq == NR_IRQS )
   15.98 +        panic("No available IRQ to bind to: increase NR_IRQS!\n");
   15.99 +
  15.100 +    return irq;
  15.101 +}
  15.102 +
  15.103 +int bind_virq_to_irq(int virq)
  15.104 +{
  15.105 +    evtchn_op_t op;
  15.106 +    int evtchn, irq;
  15.107 +
  15.108 +    spin_lock(&irq_mapping_update_lock);
  15.109 +
  15.110 +    if ( (irq = virq_to_irq[virq]) == -1 )
  15.111 +    {
  15.112 +        op.cmd              = EVTCHNOP_bind_virq;
  15.113 +        op.u.bind_virq.virq = virq;
  15.114 +        if ( HYPERVISOR_event_channel_op(&op) != 0 )
  15.115 +            panic("Failed to bind virtual IRQ %d\n", virq);
  15.116 +        evtchn = op.u.bind_virq.port;
  15.117 +
  15.118 +        irq = find_unbound_irq();
  15.119 +        evtchn_to_irq[evtchn] = irq;
  15.120 +        irq_to_evtchn[irq]    = evtchn;
  15.121 +
  15.122 +        virq_to_irq[virq] = irq;
  15.123 +    }
  15.124 +
  15.125 +    irq_bindcount[irq]++;
  15.126 +
  15.127 +    spin_unlock(&irq_mapping_update_lock);
  15.128 +    
  15.129 +    return irq;
  15.130 +}
  15.131 +
  15.132 +void unbind_virq_from_irq(int virq)
  15.133 +{
  15.134 +    evtchn_op_t op;
  15.135 +    int irq    = virq_to_irq[virq];
  15.136 +    int evtchn = irq_to_evtchn[irq];
  15.137 +
  15.138 +    spin_lock(&irq_mapping_update_lock);
  15.139 +
  15.140 +    if ( --irq_bindcount[irq] == 0 )
  15.141 +    {
  15.142 +        op.cmd          = EVTCHNOP_close;
  15.143 +        op.u.close.dom  = DOMID_SELF;
  15.144 +        op.u.close.port = evtchn;
  15.145 +        if ( HYPERVISOR_event_channel_op(&op) != 0 )
  15.146 +            panic("Failed to unbind virtual IRQ %d\n", virq);
  15.147 +
  15.148 +        evtchn_to_irq[evtchn] = -1;
  15.149 +        irq_to_evtchn[irq]    = -1;
  15.150 +        virq_to_irq[virq]     = -1;
  15.151 +    }
  15.152 +
  15.153 +    spin_unlock(&irq_mapping_update_lock);
  15.154 +}
  15.155 +
  15.156 +int bind_evtchn_to_irq(int evtchn)
  15.157 +{
  15.158 +    int irq;
  15.159 +
  15.160 +    spin_lock(&irq_mapping_update_lock);
  15.161 +
  15.162 +    if ( (irq = evtchn_to_irq[evtchn]) == -1 )
  15.163 +    {
  15.164 +        irq = find_unbound_irq();
  15.165 +        evtchn_to_irq[evtchn] = irq;
  15.166 +        irq_to_evtchn[irq]    = evtchn;
  15.167 +    }
  15.168 +
  15.169 +    irq_bindcount[irq]++;
  15.170 +
  15.171 +    spin_unlock(&irq_mapping_update_lock);
  15.172 +    
  15.173 +    return irq;
  15.174 +}
  15.175 +
  15.176 +void unbind_evtchn_from_irq(int evtchn)
  15.177 +{
  15.178 +    int irq = evtchn_to_irq[evtchn];
  15.179 +
  15.180 +    spin_lock(&irq_mapping_update_lock);
  15.181 +
  15.182 +    if ( --irq_bindcount[irq] == 0 )
  15.183 +    {
  15.184 +        evtchn_to_irq[evtchn] = -1;
  15.185 +        irq_to_evtchn[irq]    = -1;
  15.186 +    }
  15.187 +
  15.188 +    spin_unlock(&irq_mapping_update_lock);
  15.189 +}
  15.190 +
  15.191 +
  15.192 +/*
  15.193 + * Interface to generic handling in irq.c
  15.194 + */
  15.195 +
  15.196 +static unsigned int startup_dynirq(unsigned int irq)
  15.197 +{
  15.198 +    unmask_evtchn(irq_to_evtchn[irq]);
  15.199 +    return 0;
  15.200 +}
  15.201 +
  15.202 +static void shutdown_dynirq(unsigned int irq)
  15.203 +{
  15.204 +    mask_evtchn(irq_to_evtchn[irq]);
  15.205 +}
  15.206 +
  15.207 +static void enable_dynirq(unsigned int irq)
  15.208 +{
  15.209 +    unmask_evtchn(irq_to_evtchn[irq]);
  15.210 +}
  15.211 +
  15.212 +static void disable_dynirq(unsigned int irq)
  15.213 +{
  15.214 +    mask_evtchn(irq_to_evtchn[irq]);
  15.215 +}
  15.216 +
  15.217 +static void ack_dynirq(unsigned int irq)
  15.218 +{
  15.219 +    mask_evtchn(irq_to_evtchn[irq]);
  15.220 +    clear_evtchn(irq_to_evtchn[irq]);
  15.221 +}
  15.222 +
  15.223 +static void end_dynirq(unsigned int irq)
  15.224 +{
  15.225 +    if ( !(irq_desc[irq].status & IRQ_DISABLED) )
  15.226 +        unmask_evtchn(irq_to_evtchn[irq]);
  15.227 +}
  15.228 +
  15.229 +static struct hw_interrupt_type dynirq_type = {
  15.230 +    "Dynamic-irq",
  15.231 +    startup_dynirq,
  15.232 +    shutdown_dynirq,
  15.233 +    enable_dynirq,
  15.234 +    disable_dynirq,
  15.235 +    ack_dynirq,
  15.236 +    end_dynirq,
  15.237 +    NULL
  15.238 +};
  15.239 +
  15.240 +static inline void pirq_unmask_notify(int pirq)
  15.241 +{
  15.242 +    physdev_op_t op;
  15.243 +    if ( unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0])) )
  15.244 +    {
  15.245 +        op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
  15.246 +        (void)HYPERVISOR_physdev_op(&op);
  15.247 +    }
  15.248 +}
  15.249 +
  15.250 +static inline void pirq_query_unmask(int pirq)
  15.251 +{
  15.252 +    physdev_op_t op;
  15.253 +    op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
  15.254 +    op.u.irq_status_query.irq = pirq;
  15.255 +    (void)HYPERVISOR_physdev_op(&op);
  15.256 +    clear_bit(pirq, &pirq_needs_unmask_notify[0]);
  15.257 +    if ( op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY )
  15.258 +        set_bit(pirq, &pirq_needs_unmask_notify[0]);
  15.259 +}
  15.260 +
  15.261 +/*
  15.262 + * On startup, if there is no action associated with the IRQ then we are
  15.263 + * probing. In this case we should not share with others as it will confuse us.
  15.264 + */
  15.265 +#define probing_irq(_irq) (irq_desc[(_irq)].action == NULL)
  15.266 +
  15.267 +static unsigned int startup_pirq(unsigned int irq)
  15.268 +{
  15.269 +    evtchn_op_t op;
  15.270 +    int evtchn;
  15.271 +
  15.272 +    op.cmd               = EVTCHNOP_bind_pirq;
  15.273 +    op.u.bind_pirq.pirq  = irq;
  15.274 +    /* NB. We are happy to share unless we are probing. */
  15.275 +    op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
  15.276 +    if ( HYPERVISOR_event_channel_op(&op) != 0 )
  15.277 +    {
  15.278 +        if ( !probing_irq(irq) ) /* Some failures are expected when probing. */
  15.279 +            printk(KERN_INFO "Failed to obtain physical IRQ %d\n", irq);
  15.280 +        return 0;
  15.281 +    }
  15.282 +    evtchn = op.u.bind_pirq.port;
  15.283 +
  15.284 +    pirq_query_unmask(irq_to_pirq(irq));
  15.285 +
  15.286 +    evtchn_to_irq[evtchn] = irq;
  15.287 +    irq_to_evtchn[irq]    = evtchn;
  15.288 +
  15.289 +    unmask_evtchn(evtchn);
  15.290 +    pirq_unmask_notify(irq_to_pirq(irq));
  15.291 +
  15.292 +    return 0;
  15.293 +}
  15.294 +
  15.295 +static void shutdown_pirq(unsigned int irq)
  15.296 +{
  15.297 +    evtchn_op_t op;
  15.298 +    int evtchn = irq_to_evtchn[irq];
  15.299 +
  15.300 +    if ( !VALID_EVTCHN(evtchn) )
  15.301 +        return;
  15.302 +
  15.303 +    mask_evtchn(evtchn);
  15.304 +
  15.305 +    op.cmd          = EVTCHNOP_close;
  15.306 +    op.u.close.dom  = DOMID_SELF;
  15.307 +    op.u.close.port = evtchn;
  15.308 +    if ( HYPERVISOR_event_channel_op(&op) != 0 )
  15.309 +        panic("Failed to unbind physical IRQ %d\n", irq);
  15.310 +
  15.311 +    evtchn_to_irq[evtchn] = -1;
  15.312 +    irq_to_evtchn[irq]    = -1;
  15.313 +}
  15.314 +
  15.315 +static void enable_pirq(unsigned int irq)
  15.316 +{
  15.317 +    int evtchn = irq_to_evtchn[irq];
  15.318 +    if ( !VALID_EVTCHN(evtchn) )
  15.319 +        return;
  15.320 +    unmask_evtchn(evtchn);
  15.321 +    pirq_unmask_notify(irq_to_pirq(irq));
  15.322 +}
  15.323 +
  15.324 +static void disable_pirq(unsigned int irq)
  15.325 +{
  15.326 +    int evtchn = irq_to_evtchn[irq];
  15.327 +    if ( !VALID_EVTCHN(evtchn) )
  15.328 +        return;
  15.329 +    mask_evtchn(evtchn);
  15.330 +}
  15.331 +
  15.332 +static void ack_pirq(unsigned int irq)
  15.333 +{
  15.334 +    int evtchn = irq_to_evtchn[irq];
  15.335 +    if ( !VALID_EVTCHN(evtchn) )
  15.336 +        return;
  15.337 +    mask_evtchn(evtchn);
  15.338 +    clear_evtchn(evtchn);
  15.339 +}
  15.340 +
  15.341 +static void end_pirq(unsigned int irq)
  15.342 +{
  15.343 +    int evtchn = irq_to_evtchn[irq];
  15.344 +    if ( !VALID_EVTCHN(evtchn) )
  15.345 +        return;
  15.346 +    if ( !(irq_desc[irq].status & IRQ_DISABLED) )
  15.347 +    {
  15.348 +        unmask_evtchn(evtchn);
  15.349 +        pirq_unmask_notify(irq_to_pirq(irq));
  15.350 +    }
  15.351 +}
  15.352 +
  15.353 +static struct hw_interrupt_type pirq_type = {
  15.354 +    "Phys-irq",
  15.355 +    startup_pirq,
  15.356 +    shutdown_pirq,
  15.357 +    enable_pirq,
  15.358 +    disable_pirq,
  15.359 +    ack_pirq,
  15.360 +    end_pirq,
  15.361 +    NULL
  15.362 +};
  15.363 +
  15.364 +static irqreturn_t misdirect_interrupt(int irq, void *dev_id,
  15.365 +				       struct pt_regs *regs)
  15.366 +{
  15.367 +	/* nothing */
  15.368 +	return IRQ_HANDLED;
  15.369 +}
  15.370 +
  15.371 +static struct irqaction misdirect_action = {
  15.372 +    misdirect_interrupt, 
  15.373 +    SA_INTERRUPT, 
  15.374 +    0, 
  15.375 +    "misdirect", 
  15.376 +    NULL, 
  15.377 +    NULL
  15.378 +};
  15.379 +
  15.380 +void irq_suspend(void)
  15.381 +{
  15.382 +    int virq, irq, evtchn;
  15.383 +
  15.384 +    /* Unbind VIRQs from event channels. */
  15.385 +    for ( virq = 0; virq < NR_VIRQS; virq++ )
  15.386 +    {
  15.387 +        if ( (irq = virq_to_irq[virq]) == -1 )
  15.388 +            continue;
  15.389 +        evtchn = irq_to_evtchn[irq];
  15.390 +
  15.391 +        /* Mark the event channel as unused in our table. */
  15.392 +        evtchn_to_irq[evtchn] = -1;
  15.393 +        irq_to_evtchn[irq]    = -1;
  15.394 +    }
  15.395 +
  15.396 +    /*
  15.397 +     * We should now be unbound from all event channels. Stale bindings to 
  15.398 +     * PIRQs and/or inter-domain event channels will cause us to barf here.
  15.399 +     */
  15.400 +    for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
  15.401 +        if ( evtchn_to_irq[evtchn] != -1 )
  15.402 +            panic("Suspend attempted while bound to evtchn %d.\n", evtchn);
  15.403 +}
  15.404 +
  15.405 +
  15.406 +void irq_resume(void)
  15.407 +{
  15.408 +    evtchn_op_t op;
  15.409 +    int         virq, irq, evtchn;
  15.410 +
  15.411 +    for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
  15.412 +        mask_evtchn(evtchn); /* New event-channel space is not 'live' yet. */
  15.413 +
  15.414 +    for ( virq = 0; virq < NR_VIRQS; virq++ )
  15.415 +    {
  15.416 +        if ( (irq = virq_to_irq[virq]) == -1 )
  15.417 +            continue;
  15.418 +
  15.419 +        /* Get a new binding from Xen. */
  15.420 +        op.cmd              = EVTCHNOP_bind_virq;
  15.421 +        op.u.bind_virq.virq = virq;
  15.422 +        if ( HYPERVISOR_event_channel_op(&op) != 0 )
  15.423 +            panic("Failed to bind virtual IRQ %d\n", virq);
  15.424 +        evtchn = op.u.bind_virq.port;
  15.425 +        
  15.426 +        /* Record the new mapping. */
  15.427 +        evtchn_to_irq[evtchn] = irq;
  15.428 +        irq_to_evtchn[irq]    = evtchn;
  15.429 +
  15.430 +        /* Ready for use. */
  15.431 +        unmask_evtchn(evtchn);
  15.432 +    }
  15.433 +}
  15.434 +
  15.435 +void __init init_IRQ(void)
  15.436 +{
  15.437 +    int i;
  15.438 +
  15.439 +    spin_lock_init(&irq_mapping_update_lock);
  15.440 +
  15.441 +    /* No VIRQ -> IRQ mappings. */
  15.442 +    for ( i = 0; i < NR_VIRQS; i++ )
  15.443 +        virq_to_irq[i] = -1;
  15.444 +
  15.445 +    /* No event-channel -> IRQ mappings. */
  15.446 +    for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
  15.447 +    {
  15.448 +        evtchn_to_irq[i] = -1;
  15.449 +        mask_evtchn(i); /* No event channels are 'live' right now. */
  15.450 +    }
  15.451 +
  15.452 +    /* No IRQ -> event-channel mappings. */
  15.453 +    for ( i = 0; i < NR_IRQS; i++ )
  15.454 +        irq_to_evtchn[i] = -1;
  15.455 +
  15.456 +    for ( i = 0; i < NR_DYNIRQS; i++ )
  15.457 +    {
  15.458 +        /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
  15.459 +        irq_bindcount[dynirq_to_irq(i)] = 0;
  15.460 +
  15.461 +        irq_desc[dynirq_to_irq(i)].status  = IRQ_DISABLED;
  15.462 +        irq_desc[dynirq_to_irq(i)].action  = 0;
  15.463 +        irq_desc[dynirq_to_irq(i)].depth   = 1;
  15.464 +        irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
  15.465 +    }
  15.466 +
  15.467 +    for ( i = 0; i < NR_PIRQS; i++ )
  15.468 +    {
  15.469 +        /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
  15.470 +        irq_bindcount[pirq_to_irq(i)] = 1;
  15.471 +
  15.472 +        irq_desc[pirq_to_irq(i)].status  = IRQ_DISABLED;
  15.473 +        irq_desc[pirq_to_irq(i)].action  = 0;
  15.474 +        irq_desc[pirq_to_irq(i)].depth   = 1;
  15.475 +        irq_desc[pirq_to_irq(i)].handler = &pirq_type;
  15.476 +    }
  15.477 +
  15.478 +    (void)setup_irq(bind_virq_to_irq(VIRQ_MISDIRECT), &misdirect_action);
  15.479 +
  15.480 +    /* This needs to be done early, but after the IRQ subsystem is alive. */
  15.481 +    ctrl_if_init();
  15.482 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/head.S	Wed Jul 14 16:41:41 2004 +0000
    16.3 @@ -0,0 +1,191 @@
    16.4 +
    16.5 +.section __xen_guest
    16.6 +	.asciz "GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=1.3"
    16.7 +
    16.8 +.text
    16.9 +#include <linux/config.h>
   16.10 +#include <linux/threads.h>
   16.11 +#include <linux/linkage.h>
   16.12 +#include <asm/segment.h>
   16.13 +#include <asm/thread_info.h>
   16.14 +#include <asm/asm_offsets.h>
   16.15 +#include <asm/hypervisor-ifs/arch-x86_32.h>
   16.16 +
   16.17 +/*
   16.18 + * References to members of the new_cpu_data structure.
   16.19 + */
   16.20 +
   16.21 +#define X86		new_cpu_data+CPUINFO_x86
   16.22 +#define X86_VENDOR	new_cpu_data+CPUINFO_x86_vendor
   16.23 +#define X86_MODEL	new_cpu_data+CPUINFO_x86_model
   16.24 +#define X86_MASK	new_cpu_data+CPUINFO_x86_mask
   16.25 +#define X86_HARD_MATH	new_cpu_data+CPUINFO_hard_math
   16.26 +#define X86_CPUID	new_cpu_data+CPUINFO_cpuid_level
   16.27 +#define X86_CAPABILITY	new_cpu_data+CPUINFO_x86_capability
   16.28 +#define X86_VENDOR_ID	new_cpu_data+CPUINFO_x86_vendor_id
   16.29 +
   16.30 +/* Offsets in start_info structure */
   16.31 +#define MOD_START	24
   16.32 +#define MOD_LEN		28
   16.33 +                
   16.34 +ENTRY(startup_32)
   16.35 +	cld
   16.36 +
   16.37 +	/* Set up the stack pointer */
   16.38 +	lss stack_start,%esp
   16.39 +
   16.40 +	/* Copy initrd somewhere safe before it's clobbered by BSS. */
   16.41 +	mov  MOD_LEN(%esi),%ecx
   16.42 +	shr  $2,%ecx
   16.43 +	jz   2f			/* bail from copy loop if no initrd */
   16.44 +	mov  $_end,%edi
   16.45 +	add  MOD_LEN(%esi),%edi
   16.46 +	mov  MOD_START(%esi),%eax
   16.47 +	add  MOD_LEN(%esi),%eax
   16.48 +1:	sub  $4,%eax
   16.49 +	sub  $4,%edi
   16.50 +	mov  (%eax),%ebx
   16.51 +	mov  %ebx,(%edi)
   16.52 +	loop 1b
   16.53 +	mov  %edi,MOD_START(%esi)
   16.54 +
   16.55 +	/* Clear BSS first so that there are no surprises... */
   16.56 +2:	xorl %eax,%eax
   16.57 +	movl $__bss_start,%edi
   16.58 +	movl $__bss_stop,%ecx
   16.59 +	subl %edi,%ecx
   16.60 +	rep stosb
   16.61 +
   16.62 +	/* Copy the necessary stuff from start_info structure. */
   16.63 +	mov  $start_info_union,%edi
   16.64 +	mov  $128,%ecx
   16.65 +	rep movsl
   16.66 +
   16.67 +checkCPUtype:
   16.68 +
   16.69 +	/* get vendor info */
   16.70 +	xorl %eax,%eax			# call CPUID with 0 -> return vendor ID
   16.71 +	cpuid
   16.72 +	movl %eax,X86_CPUID		# save CPUID level
   16.73 +	movl %ebx,X86_VENDOR_ID		# lo 4 chars
   16.74 +	movl %edx,X86_VENDOR_ID+4	# next 4 chars
   16.75 +	movl %ecx,X86_VENDOR_ID+8	# last 4 chars
   16.76 +
   16.77 +	movl $1,%eax		# Use the CPUID instruction to get CPU type
   16.78 +	cpuid
   16.79 +	movb %al,%cl		# save reg for future use
   16.80 +	andb $0x0f,%ah		# mask processor family
   16.81 +	movb %ah,X86
   16.82 +	andb $0xf0,%al		# mask model
   16.83 +	shrb $4,%al
   16.84 +	movb %al,X86_MODEL
   16.85 +	andb $0x0f,%cl		# mask mask revision
   16.86 +	movb %cl,X86_MASK
   16.87 +	movl %edx,X86_CAPABILITY
   16.88 +
   16.89 +	xorl %eax,%eax		# Clear FS/GS and LDT
   16.90 +	movl %eax,%fs
   16.91 +	movl %eax,%gs
   16.92 +	cld		# gcc2 wants the direction flag cleared at all times
   16.93 +
   16.94 +	call start_kernel
   16.95 +L6:
   16.96 +	jmp L6			# main should never return here, but
   16.97 +				# just in case, we know what happens.
   16.98 +
   16.99 +ENTRY(lgdt_finish)
  16.100 +	movl $(__KERNEL_DS),%eax	# reload all the segment registers
  16.101 +	movw %ax,%ss			# after changing gdt.
  16.102 +
  16.103 +	movl $(__USER_DS),%eax		# DS/ES contains default USER segment
  16.104 +	movw %ax,%ds
  16.105 +	movw %ax,%es
  16.106 +
  16.107 +	popl %eax			# reload CS by intersegment return
  16.108 +	pushl $(__KERNEL_CS)
  16.109 +	pushl %eax
  16.110 +	lret
  16.111 +
  16.112 +ENTRY(stack_start)
  16.113 +	.long init_thread_union+THREAD_SIZE
  16.114 +	.long __BOOT_DS
  16.115 +
  16.116 +# XXXcl
  16.117 +.globl idt_descr
  16.118 +.globl cpu_gdt_descr
  16.119 +
  16.120 +	ALIGN
  16.121 +	.word 0				# 32-bit align idt_desc.address
  16.122 +idt_descr:
  16.123 +	.word IDT_ENTRIES*8-1		# idt contains 256 entries
  16.124 +	.long idt_table
  16.125 +# XXXcl
  16.126 +
  16.127 +# boot GDT descriptor (later on used by CPU#0):
  16.128 +	.word 0				# 32 bit align gdt_desc.address
  16.129 +cpu_gdt_descr:
  16.130 +	.word GDT_SIZE
  16.131 +	.long cpu_gdt_table
  16.132 +
  16.133 +	.fill NR_CPUS-1,8,0		# space for the other GDT descriptors
  16.134 +
  16.135 +.org 0x1000
  16.136 +ENTRY(empty_zero_page)
  16.137 +
  16.138 +.org 0x2000
  16.139 +ENTRY(swapper_pg_dir)
  16.140 +
  16.141 +.org 0x3000
  16.142 +ENTRY(cpu_gdt_table)
  16.143 +	.quad 0x0000000000000000	/* NULL descriptor */
  16.144 +	.quad 0x0000000000000000	/* 0x0b reserved */
  16.145 +	.quad 0x0000000000000000	/* 0x13 reserved */
  16.146 +	.quad 0x0000000000000000	/* 0x1b reserved */
  16.147 +	.quad 0x0000000000000000	/* 0x20 unused */
  16.148 +	.quad 0x0000000000000000	/* 0x28 unused */
  16.149 +	.quad 0x0000000000000000	/* 0x33 TLS entry 1 */
  16.150 +	.quad 0x0000000000000000	/* 0x3b TLS entry 2 */
  16.151 +	.quad 0x0000000000000000	/* 0x43 TLS entry 3 */
  16.152 +	.quad 0x0000000000000000	/* 0x4b reserved */
  16.153 +	.quad 0x0000000000000000	/* 0x53 reserved */
  16.154 +	.quad 0x0000000000000000	/* 0x5b reserved */
  16.155 +
  16.156 +	.quad 0x00cfbb000000c3ff	/* 0x60 kernel 4GB code at 0x00000000 */
  16.157 +	.quad 0x00cfb3000000c3ff	/* 0x68 kernel 4GB data at 0x00000000 */
  16.158 +	.quad 0x00cffb000000c3ff	/* 0x73 user 4GB code at 0x00000000 */
  16.159 +	.quad 0x00cff3000000c3ff	/* 0x7b user 4GB data at 0x00000000 */
  16.160 +
  16.161 +	.quad 0x0000000000000000	/* 0x80 TSS descriptor */
  16.162 +	.quad 0x0000000000000000	/* 0x88 LDT descriptor */
  16.163 +
  16.164 +	/* Segments used for calling PnP BIOS */
  16.165 +	.quad 0x0000000000000000	/* 0x90 32-bit code */
  16.166 +	.quad 0x0000000000000000	/* 0x98 16-bit code */
  16.167 +	.quad 0x0000000000000000	/* 0xa0 16-bit data */
  16.168 +	.quad 0x0000000000000000	/* 0xa8 16-bit data */
  16.169 +	.quad 0x0000000000000000	/* 0xb0 16-bit data */
  16.170 +	/*
  16.171 +	 * The APM segments have byte granularity and their bases
  16.172 +	 * and limits are set at run time.
  16.173 +	 */
  16.174 +	.quad 0x0000000000000000	/* 0xb8 APM CS    code */
  16.175 +	.quad 0x0000000000000000	/* 0xc0 APM CS 16 code (16 bit) */
  16.176 +	.quad 0x0000000000000000	/* 0xc8 APM DS    data */
  16.177 +
  16.178 +	.quad 0x0000000000000000	/* 0xd0 - unused */
  16.179 +	.quad 0x0000000000000000	/* 0xd8 - unused */
  16.180 +	.quad 0x0000000000000000	/* 0xe0 - unused */
  16.181 +	.quad 0x0000000000000000	/* 0xe8 - unused */
  16.182 +	.quad 0x0000000000000000	/* 0xf0 - unused */
  16.183 +	.quad 0x0000000000000000	/* 0xf8 - GDT entry 31: double-fault TSS */
  16.184 +	.fill GDT_ENTRIES-32,8,0
  16.185 +
  16.186 +.org 0x4000
  16.187 +ENTRY(default_ldt)
  16.188 +
  16.189 +.org 0x5000
  16.190 +/*
  16.191 + * Real beginning of normal "text" segment
  16.192 + */
  16.193 +ENTRY(stext)
  16.194 +ENTRY(_stext)
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c	Wed Jul 14 16:41:41 2004 +0000
    17.3 @@ -0,0 +1,1192 @@
    17.4 +/*
    17.5 + *	linux/arch/i386/kernel/irq.c
    17.6 + *
    17.7 + *	Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
    17.8 + *
    17.9 + * This file contains the code used by various IRQ handling routines:
   17.10 + * asking for different IRQ's should be done through these routines
   17.11 + * instead of just grabbing them. Thus setups with different IRQ numbers
   17.12 + * shouldn't result in any weird surprises, and installing new handlers
   17.13 + * should be easier.
   17.14 + */
   17.15 +
   17.16 +/*
   17.17 + * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
   17.18 + *
   17.19 + * IRQs are in fact implemented a bit like signal handlers for the kernel.
   17.20 + * Naturally it's not a 1:1 relation, but there are similarities.
   17.21 + */
   17.22 +
   17.23 +#include <linux/config.h>
   17.24 +#include <linux/errno.h>
   17.25 +#include <linux/module.h>
   17.26 +#include <linux/signal.h>
   17.27 +#include <linux/sched.h>
   17.28 +#include <linux/ioport.h>
   17.29 +#include <linux/interrupt.h>
   17.30 +#include <linux/timex.h>
   17.31 +#include <linux/slab.h>
   17.32 +#include <linux/random.h>
   17.33 +#include <linux/smp_lock.h>
   17.34 +#include <linux/init.h>
   17.35 +#include <linux/kernel_stat.h>
   17.36 +#include <linux/irq.h>
   17.37 +#include <linux/proc_fs.h>
   17.38 +#include <linux/seq_file.h>
   17.39 +#include <linux/kallsyms.h>
   17.40 +
   17.41 +#include <asm/atomic.h>
   17.42 +#include <asm/io.h>
   17.43 +#include <asm/smp.h>
   17.44 +#include <asm/system.h>
   17.45 +#include <asm/bitops.h>
   17.46 +#include <asm/uaccess.h>
   17.47 +#include <asm/pgalloc.h>
   17.48 +#include <asm/delay.h>
   17.49 +#include <asm/desc.h>
   17.50 +#include <asm/irq.h>
   17.51 +
   17.52 +/*
   17.53 + * Linux has a controller-independent x86 interrupt architecture.
   17.54 + * every controller has a 'controller-template', that is used
   17.55 + * by the main code to do the right thing. Each driver-visible
   17.56 + * interrupt source is transparently wired to the apropriate
   17.57 + * controller. Thus drivers need not be aware of the
   17.58 + * interrupt-controller.
   17.59 + *
   17.60 + * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
   17.61 + * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
   17.62 + * (IO-APICs assumed to be messaging to Pentium local-APICs)
   17.63 + *
   17.64 + * the code is designed to be easily extended with new/different
   17.65 + * interrupt controllers, without having to do assembly magic.
   17.66 + */
   17.67 +
   17.68 +/*
   17.69 + * Controller mappings for all interrupt sources:
   17.70 + */
   17.71 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
   17.72 +	[0 ... NR_IRQS-1] = {
   17.73 +		.handler = &no_irq_type,
   17.74 +		.lock = SPIN_LOCK_UNLOCKED
   17.75 +	}
   17.76 +};
   17.77 +
   17.78 +static void register_irq_proc (unsigned int irq);
   17.79 +
   17.80 +/*
   17.81 + * per-CPU IRQ handling stacks
   17.82 + */
   17.83 +#ifdef CONFIG_4KSTACKS
   17.84 +union irq_ctx *hardirq_ctx[NR_CPUS];
   17.85 +union irq_ctx *softirq_ctx[NR_CPUS];
   17.86 +#endif
   17.87 +
   17.88 +/*
   17.89 + * Special irq handlers.
   17.90 + */
   17.91 +
   17.92 +irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
   17.93 +{ return IRQ_NONE; }
   17.94 +
   17.95 +/*
   17.96 + * Generic no controller code
   17.97 + */
   17.98 +
   17.99 +static void enable_none(unsigned int irq) { }
  17.100 +static unsigned int startup_none(unsigned int irq) { return 0; }
  17.101 +static void disable_none(unsigned int irq) { }
  17.102 +static void ack_none(unsigned int irq)
  17.103 +{
  17.104 +/*
  17.105 + * 'what should we do if we get a hw irq event on an illegal vector'.
  17.106 + * each architecture has to answer this themselves, it doesn't deserve
  17.107 + * a generic callback i think.
  17.108 + */
  17.109 +#ifdef CONFIG_X86
  17.110 +	printk("unexpected IRQ trap at vector %02x\n", irq);
  17.111 +#ifdef CONFIG_X86_LOCAL_APIC
  17.112 +	/*
  17.113 +	 * Currently unexpected vectors happen only on SMP and APIC.
  17.114 +	 * We _must_ ack these because every local APIC has only N
  17.115 +	 * irq slots per priority level, and a 'hanging, unacked' IRQ
  17.116 +	 * holds up an irq slot - in excessive cases (when multiple
  17.117 +	 * unexpected vectors occur) that might lock up the APIC
  17.118 +	 * completely.
  17.119 +	 */
  17.120 +	ack_APIC_irq();
  17.121 +#endif
  17.122 +#endif
  17.123 +}
  17.124 +
  17.125 +/* startup is the same as "enable", shutdown is same as "disable" */
  17.126 +#define shutdown_none	disable_none
  17.127 +#define end_none	enable_none
  17.128 +
  17.129 +struct hw_interrupt_type no_irq_type = {
  17.130 +	"none",
  17.131 +	startup_none,
  17.132 +	shutdown_none,
  17.133 +	enable_none,
  17.134 +	disable_none,
  17.135 +	ack_none,
  17.136 +	end_none
  17.137 +};
  17.138 +
  17.139 +atomic_t irq_err_count;
  17.140 +#if defined(CONFIG_X86_IO_APIC) && defined(APIC_MISMATCH_DEBUG)
  17.141 +atomic_t irq_mis_count;
  17.142 +#endif
  17.143 +
  17.144 +/*
  17.145 + * Generic, controller-independent functions:
  17.146 + */
  17.147 +
  17.148 +int show_interrupts(struct seq_file *p, void *v)
  17.149 +{
  17.150 +	int i = *(loff_t *) v, j;
  17.151 +	struct irqaction * action;
  17.152 +	unsigned long flags;
  17.153 +
  17.154 +	if (i == 0) {
  17.155 +		seq_printf(p, "           ");
  17.156 +		for (j=0; j<NR_CPUS; j++)
  17.157 +			if (cpu_online(j))
  17.158 +				seq_printf(p, "CPU%d       ",j);
  17.159 +		seq_putc(p, '\n');
  17.160 +	}
  17.161 +
  17.162 +	if (i < NR_IRQS) {
  17.163 +		spin_lock_irqsave(&irq_desc[i].lock, flags);
  17.164 +		action = irq_desc[i].action;
  17.165 +		if (!action) 
  17.166 +			goto skip;
  17.167 +		seq_printf(p, "%3d: ",i);
  17.168 +#ifndef CONFIG_SMP
  17.169 +		seq_printf(p, "%10u ", kstat_irqs(i));
  17.170 +#else
  17.171 +		for (j = 0; j < NR_CPUS; j++)
  17.172 +			if (cpu_online(j))
  17.173 +				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
  17.174 +#endif
  17.175 +		seq_printf(p, " %14s", irq_desc[i].handler->typename);
  17.176 +		seq_printf(p, "  %s", action->name);
  17.177 +
  17.178 +		for (action=action->next; action; action = action->next)
  17.179 +			seq_printf(p, ", %s", action->name);
  17.180 +
  17.181 +		seq_putc(p, '\n');
  17.182 +skip:
  17.183 +		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
  17.184 +	} else if (i == NR_IRQS) {
  17.185 +		seq_printf(p, "NMI: ");
  17.186 +		for (j = 0; j < NR_CPUS; j++)
  17.187 +			if (cpu_online(j))
  17.188 +				seq_printf(p, "%10u ", nmi_count(j));
  17.189 +		seq_putc(p, '\n');
  17.190 +#ifdef CONFIG_X86_LOCAL_APIC
  17.191 +		seq_printf(p, "LOC: ");
  17.192 +		for (j = 0; j < NR_CPUS; j++)
  17.193 +			if (cpu_online(j))
  17.194 +				seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);
  17.195 +		seq_putc(p, '\n');
  17.196 +#endif
  17.197 +		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
  17.198 +#if defined(CONFIG_X86_IO_APIC) && defined(APIC_MISMATCH_DEBUG)
  17.199 +		seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
  17.200 +#endif
  17.201 +	}
  17.202 +	return 0;
  17.203 +}
  17.204 +
  17.205 +
  17.206 +
  17.207 +
  17.208 +#ifdef CONFIG_SMP
  17.209 +inline void synchronize_irq(unsigned int irq)
  17.210 +{
  17.211 +	while (irq_desc[irq].status & IRQ_INPROGRESS)
  17.212 +		cpu_relax();
  17.213 +}
  17.214 +#endif
  17.215 +
  17.216 +/*
  17.217 + * This should really return information about whether
  17.218 + * we should do bottom half handling etc. Right now we
  17.219 + * end up _always_ checking the bottom half, which is a
  17.220 + * waste of time and is not what some drivers would
  17.221 + * prefer.
  17.222 + */
  17.223 +asmlinkage int handle_IRQ_event(unsigned int irq,
  17.224 +		struct pt_regs *regs, struct irqaction *action)
  17.225 +{
  17.226 +	int status = 1;	/* Force the "do bottom halves" bit */
  17.227 +	int retval = 0;
  17.228 +
  17.229 +	if (!(action->flags & SA_INTERRUPT))
  17.230 +		local_irq_enable();
  17.231 +
  17.232 +	do {
  17.233 +		status |= action->flags;
  17.234 +		retval |= action->handler(irq, action->dev_id, regs);
  17.235 +		action = action->next;
  17.236 +	} while (action);
  17.237 +	if (status & SA_SAMPLE_RANDOM)
  17.238 +		add_interrupt_randomness(irq);
  17.239 +	local_irq_disable();
  17.240 +	return retval;
  17.241 +}
  17.242 +
  17.243 +static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
  17.244 +{
  17.245 +	struct irqaction *action;
  17.246 +
  17.247 +	if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
  17.248 +		printk(KERN_ERR "irq event %d: bogus return value %x\n",
  17.249 +				irq, action_ret);
  17.250 +	} else {
  17.251 +		printk(KERN_ERR "irq %d: nobody cared!\n", irq);
  17.252 +	}
  17.253 +	dump_stack();
  17.254 +	printk(KERN_ERR "handlers:\n");
  17.255 +	action = desc->action;
  17.256 +	do {
  17.257 +		printk(KERN_ERR "[<%p>]", action->handler);
  17.258 +		print_symbol(" (%s)",
  17.259 +			(unsigned long)action->handler);
  17.260 +		printk("\n");
  17.261 +		action = action->next;
  17.262 +	} while (action);
  17.263 +}
  17.264 +
  17.265 +static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
  17.266 +{
  17.267 +	static int count = 100;
  17.268 +
  17.269 +	if (count) {
  17.270 +		count--;
  17.271 +		__report_bad_irq(irq, desc, action_ret);
  17.272 +	}
  17.273 +}
  17.274 +
  17.275 +static int noirqdebug;
  17.276 +
  17.277 +static int __init noirqdebug_setup(char *str)
  17.278 +{
  17.279 +	noirqdebug = 1;
  17.280 +	printk("IRQ lockup detection disabled\n");
  17.281 +	return 1;
  17.282 +}
  17.283 +
  17.284 +__setup("noirqdebug", noirqdebug_setup);
  17.285 +
  17.286 +/*
  17.287 + * If 99,900 of the previous 100,000 interrupts have not been handled then
  17.288 + * assume that the IRQ is stuck in some manner.  Drop a diagnostic and try to
  17.289 + * turn the IRQ off.
  17.290 + *
  17.291 + * (The other 100-of-100,000 interrupts may have been a correctly-functioning
  17.292 + *  device sharing an IRQ with the failing one)
  17.293 + *
  17.294 + * Called under desc->lock
  17.295 + */
  17.296 +static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret)
  17.297 +{
  17.298 +	if (action_ret != IRQ_HANDLED) {
  17.299 +		desc->irqs_unhandled++;
  17.300 +		if (action_ret != IRQ_NONE)
  17.301 +			report_bad_irq(irq, desc, action_ret);
  17.302 +	}
  17.303 +
  17.304 +	desc->irq_count++;
  17.305 +	if (desc->irq_count < 100000)
  17.306 +		return;
  17.307 +
  17.308 +	desc->irq_count = 0;
  17.309 +	if (desc->irqs_unhandled > 99900) {
  17.310 +		/*
  17.311 +		 * The interrupt is stuck
  17.312 +		 */
  17.313 +		__report_bad_irq(irq, desc, action_ret);
  17.314 +		/*
  17.315 +		 * Now kill the IRQ
  17.316 +		 */
  17.317 +		printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
  17.318 +		desc->status |= IRQ_DISABLED;
  17.319 +		desc->handler->disable(irq);
  17.320 +	}
  17.321 +	desc->irqs_unhandled = 0;
  17.322 +}
  17.323 +
  17.324 +/*
  17.325 + * Generic enable/disable code: this just calls
  17.326 + * down into the PIC-specific version for the actual
  17.327 + * hardware disable after having gotten the irq
  17.328 + * controller lock. 
  17.329 + */
  17.330 + 
  17.331 +/**
  17.332 + *	disable_irq_nosync - disable an irq without waiting
  17.333 + *	@irq: Interrupt to disable
  17.334 + *
  17.335 + *	Disable the selected interrupt line.  Disables and Enables are
  17.336 + *	nested.
  17.337 + *	Unlike disable_irq(), this function does not ensure existing
  17.338 + *	instances of the IRQ handler have completed before returning.
  17.339 + *
  17.340 + *	This function may be called from IRQ context.
  17.341 + */
  17.342 + 
  17.343 +inline void disable_irq_nosync(unsigned int irq)
  17.344 +{
  17.345 +	irq_desc_t *desc = irq_desc + irq;
  17.346 +	unsigned long flags;
  17.347 +
  17.348 +	spin_lock_irqsave(&desc->lock, flags);
  17.349 +	if (!desc->depth++) {
  17.350 +		desc->status |= IRQ_DISABLED;
  17.351 +		desc->handler->disable(irq);
  17.352 +	}
  17.353 +	spin_unlock_irqrestore(&desc->lock, flags);
  17.354 +}
  17.355 +
  17.356 +/**
  17.357 + *	disable_irq - disable an irq and wait for completion
  17.358 + *	@irq: Interrupt to disable
  17.359 + *
  17.360 + *	Disable the selected interrupt line.  Enables and Disables are
  17.361 + *	nested.
  17.362 + *	This function waits for any pending IRQ handlers for this interrupt
  17.363 + *	to complete before returning. If you use this function while
  17.364 + *	holding a resource the IRQ handler may need you will deadlock.
  17.365 + *
  17.366 + *	This function may be called - with care - from IRQ context.
  17.367 + */
  17.368 + 
  17.369 +void disable_irq(unsigned int irq)
  17.370 +{
  17.371 +	irq_desc_t *desc = irq_desc + irq;
  17.372 +	disable_irq_nosync(irq);
  17.373 +	if (desc->action)
  17.374 +		synchronize_irq(irq);
  17.375 +}
  17.376 +
  17.377 +/**
  17.378 + *	enable_irq - enable handling of an irq
  17.379 + *	@irq: Interrupt to enable
  17.380 + *
  17.381 + *	Undoes the effect of one call to disable_irq().  If this
  17.382 + *	matches the last disable, processing of interrupts on this
  17.383 + *	IRQ line is re-enabled.
  17.384 + *
  17.385 + *	This function may be called from IRQ context.
  17.386 + */
  17.387 + 
  17.388 +void enable_irq(unsigned int irq)
  17.389 +{
  17.390 +	irq_desc_t *desc = irq_desc + irq;
  17.391 +	unsigned long flags;
  17.392 +
  17.393 +	spin_lock_irqsave(&desc->lock, flags);
  17.394 +	switch (desc->depth) {
  17.395 +	case 1: {
  17.396 +		unsigned int status = desc->status & ~IRQ_DISABLED;
  17.397 +		desc->status = status;
  17.398 +		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
  17.399 +			desc->status = status | IRQ_REPLAY;
  17.400 +			hw_resend_irq(desc->handler,irq);
  17.401 +		}
  17.402 +		desc->handler->enable(irq);
  17.403 +		/* fall-through */
  17.404 +	}
  17.405 +	default:
  17.406 +		desc->depth--;
  17.407 +		break;
  17.408 +	case 0:
  17.409 +		printk("enable_irq(%u) unbalanced from %p\n", irq,
  17.410 +		       __builtin_return_address(0));
  17.411 +	}
  17.412 +	spin_unlock_irqrestore(&desc->lock, flags);
  17.413 +}
  17.414 +
  17.415 +/*
  17.416 + * do_IRQ handles all normal device IRQ's (the special
  17.417 + * SMP cross-CPU interrupts have their own specific
  17.418 + * handlers).
  17.419 + */
  17.420 +asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
  17.421 +{	
  17.422 +	/* 
  17.423 +	 * We ack quickly, we don't want the irq controller
  17.424 +	 * thinking we're snobs just because some other CPU has
  17.425 +	 * disabled global interrupts (we have already done the
  17.426 +	 * INT_ACK cycles, it's too late to try to pretend to the
  17.427 +	 * controller that we aren't taking the interrupt).
  17.428 +	 *
  17.429 +	 * 0 return value means that this irq is already being
  17.430 +	 * handled by some other CPU. (or is disabled)
  17.431 +	 */
  17.432 +	irq_desc_t *desc = irq_desc + irq;
  17.433 +	struct irqaction * action;
  17.434 +	unsigned int status;
  17.435 +
  17.436 +	irq_enter();
  17.437 +
  17.438 +#ifdef CONFIG_DEBUG_STACKOVERFLOW
  17.439 +	/* Debugging check for stack overflow: is there less than 1KB free? */
  17.440 +	{
  17.441 +		long esp;
  17.442 +
  17.443 +		__asm__ __volatile__("andl %%esp,%0" :
  17.444 +					"=r" (esp) : "0" (THREAD_SIZE - 1));
  17.445 +		if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) {
  17.446 +			printk("do_IRQ: stack overflow: %ld\n",
  17.447 +				esp - sizeof(struct thread_info));
  17.448 +			dump_stack();
  17.449 +		}
  17.450 +	}
  17.451 +#endif
  17.452 +	kstat_this_cpu.irqs[irq]++;
  17.453 +	spin_lock(&desc->lock);
  17.454 +	desc->handler->ack(irq);
  17.455 +	/*
  17.456 +	   REPLAY is when Linux resends an IRQ that was dropped earlier
  17.457 +	   WAITING is used by probe to mark irqs that are being tested
  17.458 +	   */
  17.459 +	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
  17.460 +	status |= IRQ_PENDING; /* we _want_ to handle it */
  17.461 +
  17.462 +	/*
  17.463 +	 * If the IRQ is disabled for whatever reason, we cannot
  17.464 +	 * use the action we have.
  17.465 +	 */
  17.466 +	action = NULL;
  17.467 +	if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
  17.468 +		action = desc->action;
  17.469 +		status &= ~IRQ_PENDING; /* we commit to handling */
  17.470 +		status |= IRQ_INPROGRESS; /* we are handling it */
  17.471 +	}
  17.472 +	desc->status = status;
  17.473 +
  17.474 +	/*
  17.475 +	 * If there is no IRQ handler or it was disabled, exit early.
  17.476 +	   Since we set PENDING, if another processor is handling
  17.477 +	   a different instance of this same irq, the other processor
  17.478 +	   will take care of it.
  17.479 +	 */
  17.480 +	if (unlikely(!action))
  17.481 +		goto out;
  17.482 +
  17.483 +	/*
  17.484 +	 * Edge triggered interrupts need to remember
  17.485 +	 * pending events.
  17.486 +	 * This applies to any hw interrupts that allow a second
  17.487 +	 * instance of the same irq to arrive while we are in do_IRQ
  17.488 +	 * or in the handler. But the code here only handles the _second_
  17.489 +	 * instance of the irq, not the third or fourth. So it is mostly
  17.490 +	 * useful for irq hardware that does not mask cleanly in an
  17.491 +	 * SMP environment.
  17.492 +	 */
  17.493 +#ifdef CONFIG_4KSTACKS
  17.494 +
  17.495 +	for (;;) {
  17.496 +		irqreturn_t action_ret;
  17.497 +		u32 *isp;
  17.498 +		union irq_ctx * curctx;
  17.499 +		union irq_ctx * irqctx;
  17.500 +
  17.501 +		curctx = (union irq_ctx *) current_thread_info();
  17.502 +		irqctx = hardirq_ctx[smp_processor_id()];
  17.503 +
  17.504 +		spin_unlock(&desc->lock);
  17.505 +
  17.506 +		/*
  17.507 +		 * this is where we switch to the IRQ stack. However, if we are already using
  17.508 +		 * the IRQ stack (because we interrupted a hardirq handler) we can't do that
  17.509 +		 * and just have to keep using the current stack (which is the irq stack already
  17.510 +		 * after all)
  17.511 +		 */
  17.512 +
  17.513 +		if (curctx == irqctx)
  17.514 +			action_ret = handle_IRQ_event(irq, regs, action);
  17.515 +		else {
  17.516 +			/* build the stack frame on the IRQ stack */
  17.517 +			isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
  17.518 +			irqctx->tinfo.task = curctx->tinfo.task;
  17.519 +			irqctx->tinfo.previous_esp = current_stack_pointer();
  17.520 +
  17.521 +			*--isp = (u32) action;
  17.522 +			*--isp = (u32) regs;
  17.523 +			*--isp = (u32) irq;
  17.524 +
  17.525 +			asm volatile(
  17.526 +				"       xchgl   %%ebx,%%esp     \n"
  17.527 +				"       call    handle_IRQ_event \n"
  17.528 +				"       xchgl   %%ebx,%%esp     \n"
  17.529 +				: "=a"(action_ret)
  17.530 +				: "b"(isp)
  17.531 +				: "memory", "cc", "edx", "ecx"
  17.532 +			);
  17.533 +
  17.534 +
  17.535 +		}
  17.536 +		spin_lock(&desc->lock);
  17.537 +		if (!noirqdebug)
  17.538 +			note_interrupt(irq, desc, action_ret);
  17.539 +		if (curctx != irqctx)
  17.540 +			irqctx->tinfo.task = NULL;
  17.541 +		if (likely(!(desc->status & IRQ_PENDING)))
  17.542 +			break;
  17.543 +		desc->status &= ~IRQ_PENDING;
  17.544 +	}
  17.545 +
  17.546 +#else
  17.547 +
  17.548 +	for (;;) {
  17.549 +		irqreturn_t action_ret;
  17.550 +
  17.551 +		spin_unlock(&desc->lock);
  17.552 +
  17.553 +		action_ret = handle_IRQ_event(irq, regs, action);
  17.554 +
  17.555 +		spin_lock(&desc->lock);
  17.556 +		if (!noirqdebug)
  17.557 +			note_interrupt(irq, desc, action_ret);
  17.558 +		if (likely(!(desc->status & IRQ_PENDING)))
  17.559 +			break;
  17.560 +		desc->status &= ~IRQ_PENDING;
  17.561 +	}
  17.562 +#endif
  17.563 +	desc->status &= ~IRQ_INPROGRESS;
  17.564 +
  17.565 +out:
  17.566 +	/*
  17.567 +	 * The ->end() handler has to deal with interrupts which got
  17.568 +	 * disabled while the handler was running.
  17.569 +	 */
  17.570 +	desc->handler->end(irq);
  17.571 +	spin_unlock(&desc->lock);
  17.572 +
  17.573 +	irq_exit();
  17.574 +
  17.575 +	return 1;
  17.576 +}
  17.577 +
  17.578 +int can_request_irq(unsigned int irq, unsigned long irqflags)
  17.579 +{
  17.580 +	struct irqaction *action;
  17.581 +
  17.582 +	if (irq >= NR_IRQS)
  17.583 +		return 0;
  17.584 +	action = irq_desc[irq].action;
  17.585 +	if (action) {
  17.586 +		if (irqflags & action->flags & SA_SHIRQ)
  17.587 +			action = NULL;
  17.588 +	}
  17.589 +	return !action;
  17.590 +}
  17.591 +
  17.592 +/**
  17.593 + *	request_irq - allocate an interrupt line
  17.594 + *	@irq: Interrupt line to allocate
  17.595 + *	@handler: Function to be called when the IRQ occurs
  17.596 + *	@irqflags: Interrupt type flags
  17.597 + *	@devname: An ascii name for the claiming device
  17.598 + *	@dev_id: A cookie passed back to the handler function
  17.599 + *
  17.600 + *	This call allocates interrupt resources and enables the
  17.601 + *	interrupt line and IRQ handling. From the point this
  17.602 + *	call is made your handler function may be invoked. Since
  17.603 + *	your handler function must clear any interrupt the board 
  17.604 + *	raises, you must take care both to initialise your hardware
  17.605 + *	and to set up the interrupt handler in the right order.
  17.606 + *
  17.607 + *	Dev_id must be globally unique. Normally the address of the
  17.608 + *	device data structure is used as the cookie. Since the handler
  17.609 + *	receives this value it makes sense to use it.
  17.610 + *
  17.611 + *	If your interrupt is shared you must pass a non NULL dev_id
  17.612 + *	as this is required when freeing the interrupt.
  17.613 + *
  17.614 + *	Flags:
  17.615 + *
  17.616 + *	SA_SHIRQ		Interrupt is shared
  17.617 + *
  17.618 + *	SA_INTERRUPT		Disable local interrupts while processing
  17.619 + *
  17.620 + *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
  17.621 + *
  17.622 + */
  17.623 + 
  17.624 +int request_irq(unsigned int irq, 
  17.625 +		irqreturn_t (*handler)(int, void *, struct pt_regs *),
  17.626 +		unsigned long irqflags, 
  17.627 +		const char * devname,
  17.628 +		void *dev_id)
  17.629 +{
  17.630 +	int retval;
  17.631 +	struct irqaction * action;
  17.632 +
  17.633 +#if 1
  17.634 +	/*
  17.635 +	 * Sanity-check: shared interrupts should REALLY pass in
  17.636 +	 * a real dev-ID, otherwise we'll have trouble later trying
  17.637 +	 * to figure out which interrupt is which (messes up the
  17.638 +	 * interrupt freeing logic etc).
  17.639 +	 */
  17.640 +	if (irqflags & SA_SHIRQ) {
  17.641 +		if (!dev_id)
  17.642 +			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
  17.643 +	}
  17.644 +#endif
  17.645 +
  17.646 +	if (irq >= NR_IRQS)
  17.647 +		return -EINVAL;
  17.648 +	if (!handler)
  17.649 +		return -EINVAL;
  17.650 +
  17.651 +	action = (struct irqaction *)
  17.652 +			kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
  17.653 +	if (!action)
  17.654 +		return -ENOMEM;
  17.655 +
  17.656 +	action->handler = handler;
  17.657 +	action->flags = irqflags;
  17.658 +	action->mask = 0;
  17.659 +	action->name = devname;
  17.660 +	action->next = NULL;
  17.661 +	action->dev_id = dev_id;
  17.662 +
  17.663 +	retval = setup_irq(irq, action);
  17.664 +	if (retval)
  17.665 +		kfree(action);
  17.666 +	return retval;
  17.667 +}
  17.668 +
  17.669 +EXPORT_SYMBOL(request_irq);
  17.670 +
  17.671 +/**
  17.672 + *	free_irq - free an interrupt
  17.673 + *	@irq: Interrupt line to free
  17.674 + *	@dev_id: Device identity to free
  17.675 + *
  17.676 + *	Remove an interrupt handler. The handler is removed and if the
  17.677 + *	interrupt line is no longer in use by any driver it is disabled.
  17.678 + *	On a shared IRQ the caller must ensure the interrupt is disabled
  17.679 + *	on the card it drives before calling this function. The function
  17.680 + *	does not return until any executing interrupts for this IRQ
  17.681 + *	have completed.
  17.682 + *
  17.683 + *	This function must not be called from interrupt context. 
  17.684 + */
  17.685 + 
  17.686 +void free_irq(unsigned int irq, void *dev_id)
  17.687 +{
  17.688 +	irq_desc_t *desc;
  17.689 +	struct irqaction **p;
  17.690 +	unsigned long flags;
  17.691 +
  17.692 +	if (irq >= NR_IRQS)
  17.693 +		return;
  17.694 +
  17.695 +	desc = irq_desc + irq;
  17.696 +	spin_lock_irqsave(&desc->lock,flags);
  17.697 +	p = &desc->action;
  17.698 +	for (;;) {
  17.699 +		struct irqaction * action = *p;
  17.700 +		if (action) {
  17.701 +			struct irqaction **pp = p;
  17.702 +			p = &action->next;
  17.703 +			if (action->dev_id != dev_id)
  17.704 +				continue;
  17.705 +
  17.706 +			/* Found it - now remove it from the list of entries */
  17.707 +			*pp = action->next;
  17.708 +			if (!desc->action) {
  17.709 +				desc->status |= IRQ_DISABLED;
  17.710 +				desc->handler->shutdown(irq);
  17.711 +			}
  17.712 +			spin_unlock_irqrestore(&desc->lock,flags);
  17.713 +
  17.714 +			/* Wait to make sure it's not being used on another CPU */
  17.715 +			synchronize_irq(irq);
  17.716 +			kfree(action);
  17.717 +			return;
  17.718 +		}
  17.719 +		printk("Trying to free free IRQ%d\n",irq);
  17.720 +		spin_unlock_irqrestore(&desc->lock,flags);
  17.721 +		return;
  17.722 +	}
  17.723 +}
  17.724 +
  17.725 +EXPORT_SYMBOL(free_irq);
  17.726 +
  17.727 +/*
  17.728 + * IRQ autodetection code..
  17.729 + *
  17.730 + * This depends on the fact that any interrupt that
  17.731 + * comes in on to an unassigned handler will get stuck
  17.732 + * with "IRQ_WAITING" cleared and the interrupt
  17.733 + * disabled.
  17.734 + */
  17.735 +
  17.736 +static DECLARE_MUTEX(probe_sem);
  17.737 +
  17.738 +/**
  17.739 + *	probe_irq_on	- begin an interrupt autodetect
  17.740 + *
  17.741 + *	Commence probing for an interrupt. The interrupts are scanned
  17.742 + *	and a mask of potential interrupt lines is returned.
  17.743 + *
  17.744 + */
  17.745 + 
  17.746 +unsigned long probe_irq_on(void)
  17.747 +{
  17.748 +	unsigned int i;
  17.749 +	irq_desc_t *desc;
  17.750 +	unsigned long val;
  17.751 +	unsigned long delay;
  17.752 +
  17.753 +	down(&probe_sem);
  17.754 +	/* 
  17.755 +	 * something may have generated an irq long ago and we want to
  17.756 +	 * flush such a longstanding irq before considering it as spurious. 
  17.757 +	 */
  17.758 +	for (i = NR_PIRQS-1; i > 0; i--)  {
  17.759 +		desc = irq_desc + i;
  17.760 +
  17.761 +		spin_lock_irq(&desc->lock);
  17.762 +		if (!irq_desc[i].action) 
  17.763 +			irq_desc[i].handler->startup(i);
  17.764 +		spin_unlock_irq(&desc->lock);
  17.765 +	}
  17.766 +
  17.767 +	/* Wait for longstanding interrupts to trigger. */
  17.768 +	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
  17.769 +		/* about 20ms delay */ barrier();
  17.770 +
  17.771 +	/*
  17.772 +	 * enable any unassigned irqs
  17.773 +	 * (we must startup again here because if a longstanding irq
  17.774 +	 * happened in the previous stage, it may have masked itself)
  17.775 +	 */
  17.776 +	for (i = NR_PIRQS-1; i > 0; i--) {
  17.777 +		desc = irq_desc + i;
  17.778 +
  17.779 +		spin_lock_irq(&desc->lock);
  17.780 +		if (!desc->action) {
  17.781 +			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
  17.782 +			if (desc->handler->startup(i))
  17.783 +				desc->status |= IRQ_PENDING;
  17.784 +		}
  17.785 +		spin_unlock_irq(&desc->lock);
  17.786 +	}
  17.787 +
  17.788 +	/*
  17.789 +	 * Wait for spurious interrupts to trigger
  17.790 +	 */
  17.791 +	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
  17.792 +		/* about 100ms delay */ barrier();
  17.793 +
  17.794 +	/*
  17.795 +	 * Now filter out any obviously spurious interrupts
  17.796 +	 */
  17.797 +	val = 0;
  17.798 +	for (i = 0; i < NR_PIRQS; i++) {
  17.799 +		irq_desc_t *desc = irq_desc + i;
  17.800 +		unsigned int status;
  17.801 +
  17.802 +		spin_lock_irq(&desc->lock);
  17.803 +		status = desc->status;
  17.804 +
  17.805 +		if (status & IRQ_AUTODETECT) {
  17.806 +			/* It triggered already - consider it spurious. */
  17.807 +			if (!(status & IRQ_WAITING)) {
  17.808 +				desc->status = status & ~IRQ_AUTODETECT;
  17.809 +				desc->handler->shutdown(i);
  17.810 +			} else
  17.811 +				if (i < 32)
  17.812 +					val |= 1 << i;
  17.813 +		}
  17.814 +		spin_unlock_irq(&desc->lock);
  17.815 +	}
  17.816 +
  17.817 +	return val;
  17.818 +}
  17.819 +
  17.820 +EXPORT_SYMBOL(probe_irq_on);
  17.821 +
  17.822 +/*
  17.823 + * Return a mask of triggered interrupts (this
  17.824 + * can handle only legacy ISA interrupts).
  17.825 + */
  17.826 + 
  17.827 +/**
  17.828 + *	probe_irq_mask - scan a bitmap of interrupt lines
  17.829 + *	@val:	mask of interrupts to consider
  17.830 + *
  17.831 + *	Scan the ISA bus interrupt lines and return a bitmap of
  17.832 + *	active interrupts. The interrupt probe logic state is then
  17.833 + *	returned to its previous value.
  17.834 + *
  17.835 + *	Note: we need to scan all the irq's even though we will
  17.836 + *	only return ISA irq numbers - just so that we reset them
  17.837 + *	all to a known state.
  17.838 + */
  17.839 +unsigned int probe_irq_mask(unsigned long val)
  17.840 +{
  17.841 +	int i;
  17.842 +	unsigned int mask;
  17.843 +
  17.844 +	mask = 0;
  17.845 +	for (i = 0; i < NR_PIRQS; i++) {
  17.846 +		irq_desc_t *desc = irq_desc + i;
  17.847 +		unsigned int status;
  17.848 +
  17.849 +		spin_lock_irq(&desc->lock);
  17.850 +		status = desc->status;
  17.851 +
  17.852 +		if (status & IRQ_AUTODETECT) {
  17.853 +			if (i < 16 && !(status & IRQ_WAITING))
  17.854 +				mask |= 1 << i;
  17.855 +
  17.856 +			desc->status = status & ~IRQ_AUTODETECT;
  17.857 +			desc->handler->shutdown(i);
  17.858 +		}
  17.859 +		spin_unlock_irq(&desc->lock);
  17.860 +	}
  17.861 +	up(&probe_sem);
  17.862 +
  17.863 +	return mask & val;
  17.864 +}
  17.865 +
  17.866 +/*
  17.867 + * Return the one interrupt that triggered (this can
  17.868 + * handle any interrupt source).
  17.869 + */
  17.870 +
  17.871 +/**
  17.872 + *	probe_irq_off	- end an interrupt autodetect
  17.873 + *	@val: mask of potential interrupts (unused)
  17.874 + *
  17.875 + *	Scans the unused interrupt lines and returns the line which
  17.876 + *	appears to have triggered the interrupt. If no interrupt was
  17.877 + *	found then zero is returned. If more than one interrupt is
  17.878 + *	found then minus the first candidate is returned to indicate
  17.879 + *	their is doubt.
  17.880 + *
  17.881 + *	The interrupt probe logic state is returned to its previous
  17.882 + *	value.
  17.883 + *
  17.884 + *	BUGS: When used in a module (which arguably shouldnt happen)
  17.885 + *	nothing prevents two IRQ probe callers from overlapping. The
  17.886 + *	results of this are non-optimal.
  17.887 + */
  17.888 + 
  17.889 +int probe_irq_off(unsigned long val)
  17.890 +{
  17.891 +	int i, irq_found, nr_irqs;
  17.892 +
  17.893 +	nr_irqs = 0;
  17.894 +	irq_found = 0;
  17.895 +	for (i = 0; i < NR_PIRQS; i++) {
  17.896 +		irq_desc_t *desc = irq_desc + i;
  17.897 +		unsigned int status;
  17.898 +
  17.899 +		spin_lock_irq(&desc->lock);
  17.900 +		status = desc->status;
  17.901 +
  17.902 +		if (status & IRQ_AUTODETECT) {
  17.903 +			if (!(status & IRQ_WAITING)) {
  17.904 +				if (!nr_irqs)
  17.905 +					irq_found = i;
  17.906 +				nr_irqs++;
  17.907 +			}
  17.908 +			desc->status = status & ~IRQ_AUTODETECT;
  17.909 +			desc->handler->shutdown(i);
  17.910 +		}
  17.911 +		spin_unlock_irq(&desc->lock);
  17.912 +	}
  17.913 +	up(&probe_sem);
  17.914 +
  17.915 +	if (nr_irqs > 1)
  17.916 +		irq_found = -irq_found;
  17.917 +	return irq_found;
  17.918 +}
  17.919 +
  17.920 +EXPORT_SYMBOL(probe_irq_off);
  17.921 +
  17.922 +/* this was setup_x86_irq but it seems pretty generic */
  17.923 +int setup_irq(unsigned int irq, struct irqaction * new)
  17.924 +{
  17.925 +	int shared = 0;
  17.926 +	unsigned long flags;
  17.927 +	struct irqaction *old, **p;
  17.928 +	irq_desc_t *desc = irq_desc + irq;
  17.929 +
  17.930 +	if (desc->handler == &no_irq_type)
  17.931 +		return -ENOSYS;
  17.932 +	/*
  17.933 +	 * Some drivers like serial.c use request_irq() heavily,
  17.934 +	 * so we have to be careful not to interfere with a
  17.935 +	 * running system.
  17.936 +	 */
  17.937 +	if (new->flags & SA_SAMPLE_RANDOM) {
  17.938 +		/*
  17.939 +		 * This function might sleep, we want to call it first,
  17.940 +		 * outside of the atomic block.
  17.941 +		 * Yes, this might clear the entropy pool if the wrong
  17.942 +		 * driver is attempted to be loaded, without actually
  17.943 +		 * installing a new handler, but is this really a problem,
  17.944 +		 * only the sysadmin is able to do this.
  17.945 +		 */
  17.946 +		rand_initialize_irq(irq);
  17.947 +	}
  17.948 +
  17.949 +	/*
  17.950 +	 * The following block of code has to be executed atomically
  17.951 +	 */
  17.952 +	spin_lock_irqsave(&desc->lock,flags);
  17.953 +	p = &desc->action;
  17.954 +	if ((old = *p) != NULL) {
  17.955 +		/* Can't share interrupts unless both agree to */
  17.956 +		if (!(old->flags & new->flags & SA_SHIRQ)) {
  17.957 +			spin_unlock_irqrestore(&desc->lock,flags);
  17.958 +			return -EBUSY;
  17.959 +		}
  17.960 +
  17.961 +		/* add new interrupt at end of irq queue */
  17.962 +		do {
  17.963 +			p = &old->next;
  17.964 +			old = *p;
  17.965 +		} while (old);
  17.966 +		shared = 1;
  17.967 +	}
  17.968 +
  17.969 +	*p = new;
  17.970 +
  17.971 +	if (!shared) {
  17.972 +		desc->depth = 0;
  17.973 +		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
  17.974 +		desc->handler->startup(irq);
  17.975 +	}
  17.976 +	spin_unlock_irqrestore(&desc->lock,flags);
  17.977 +
  17.978 +	register_irq_proc(irq);
  17.979 +	return 0;
  17.980 +}
  17.981 +
  17.982 +static struct proc_dir_entry * root_irq_dir;
  17.983 +static struct proc_dir_entry * irq_dir [NR_IRQS];
  17.984 +
  17.985 +#ifdef CONFIG_SMP
  17.986 +
  17.987 +static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
  17.988 +
  17.989 +cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
  17.990 +
  17.991 +static int irq_affinity_read_proc(char *page, char **start, off_t off,
  17.992 +			int count, int *eof, void *data)
  17.993 +{
  17.994 +	int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
  17.995 +	if (count - len < 2)
  17.996 +		return -EINVAL;
  17.997 +	len += sprintf(page + len, "\n");
  17.998 +	return len;
  17.999 +}
 17.1000 +
 17.1001 +static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
 17.1002 +					unsigned long count, void *data)
 17.1003 +{
 17.1004 +	int irq = (long)data, full_count = count, err;
 17.1005 +	cpumask_t new_value, tmp;
 17.1006 +
 17.1007 +	if (!irq_desc[irq].handler->set_affinity)
 17.1008 +		return -EIO;
 17.1009 +
 17.1010 +	err = cpumask_parse(buffer, count, new_value);
 17.1011 +	if (err)
 17.1012 +		return err;
 17.1013 +
 17.1014 +	/*
 17.1015 +	 * Do not allow disabling IRQs completely - it's a too easy
 17.1016 +	 * way to make the system unusable accidentally :-) At least
 17.1017 +	 * one online CPU still has to be targeted.
 17.1018 +	 */
 17.1019 +	cpus_and(tmp, new_value, cpu_online_map);
 17.1020 +	if (cpus_empty(tmp))
 17.1021 +		return -EINVAL;
 17.1022 +
 17.1023 +	irq_affinity[irq] = new_value;
 17.1024 +	irq_desc[irq].handler->set_affinity(irq,
 17.1025 +					cpumask_of_cpu(first_cpu(new_value)));
 17.1026 +
 17.1027 +	return full_count;
 17.1028 +}
 17.1029 +
 17.1030 +#endif
 17.1031 +
 17.1032 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
 17.1033 +			int count, int *eof, void *data)
 17.1034 +{
 17.1035 +	int len = cpumask_scnprintf(page, count, *(cpumask_t *)data);
 17.1036 +	if (count - len < 2)
 17.1037 +		return -EINVAL;
 17.1038 +	len += sprintf(page + len, "\n");
 17.1039 +	return len;
 17.1040 +}
 17.1041 +
 17.1042 +static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
 17.1043 +					unsigned long count, void *data)
 17.1044 +{
 17.1045 +	cpumask_t *mask = (cpumask_t *)data;
 17.1046 +	unsigned long full_count = count, err;
 17.1047 +	cpumask_t new_value;
 17.1048 +
 17.1049 +	err = cpumask_parse(buffer, count, new_value);
 17.1050 +	if (err)
 17.1051 +		return err;
 17.1052 +
 17.1053 +	*mask = new_value;
 17.1054 +	return full_count;
 17.1055 +}
 17.1056 +
 17.1057 +#define MAX_NAMELEN 10
 17.1058 +
 17.1059 +static void register_irq_proc (unsigned int irq)
 17.1060 +{
 17.1061 +	char name [MAX_NAMELEN];
 17.1062 +
 17.1063 +	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
 17.1064 +			irq_dir[irq])
 17.1065 +		return;
 17.1066 +
 17.1067 +	memset(name, 0, MAX_NAMELEN);
 17.1068 +	sprintf(name, "%d", irq);
 17.1069 +
 17.1070 +	/* create /proc/irq/1234 */
 17.1071 +	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
 17.1072 +
 17.1073 +#ifdef CONFIG_SMP
 17.1074 +	{
 17.1075 +		struct proc_dir_entry *entry;
 17.1076 +
 17.1077 +		/* create /proc/irq/1234/smp_affinity */
 17.1078 +		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
 17.1079 +
 17.1080 +		if (entry) {
 17.1081 +			entry->nlink = 1;
 17.1082 +			entry->data = (void *)(long)irq;
 17.1083 +			entry->read_proc = irq_affinity_read_proc;
 17.1084 +			entry->write_proc = irq_affinity_write_proc;
 17.1085 +		}
 17.1086 +
 17.1087 +		smp_affinity_entry[irq] = entry;
 17.1088 +	}
 17.1089 +#endif
 17.1090 +}
 17.1091 +
 17.1092 +unsigned long prof_cpu_mask = -1;
 17.1093 +
 17.1094 +void init_irq_proc (void)
 17.1095 +{
 17.1096 +	struct proc_dir_entry *entry;
 17.1097 +	int i;
 17.1098 +
 17.1099 +	/* create /proc/irq */
 17.1100 +	root_irq_dir = proc_mkdir("irq", 0);
 17.1101 +
 17.1102 +	/* create /proc/irq/prof_cpu_mask */
 17.1103 +	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
 17.1104 +
 17.1105 +	if (!entry)
 17.1106 +	    return;
 17.1107 +
 17.1108 +	entry->nlink = 1;
 17.1109 +	entry->data = (void *)&prof_cpu_mask;
 17.1110 +	entry->read_proc = prof_cpu_mask_read_proc;
 17.1111 +	entry->write_proc = prof_cpu_mask_write_proc;
 17.1112 +
 17.1113 +	/*
 17.1114 +	 * Create entries for all existing IRQs.
 17.1115 +	 */
 17.1116 +	for (i = 0; i < NR_IRQS; i++)
 17.1117 +		register_irq_proc(i);
 17.1118 +}
 17.1119 +
 17.1120 +
 17.1121 +#ifdef CONFIG_4KSTACKS
 17.1122 +static char softirq_stack[NR_CPUS * THREAD_SIZE]  __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
 17.1123 +static char hardirq_stack[NR_CPUS * THREAD_SIZE]  __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
 17.1124 +
 17.1125 +/*
 17.1126 + * allocate per-cpu stacks for hardirq and for softirq processing
 17.1127 + */
 17.1128 +void irq_ctx_init(int cpu)
 17.1129 +{
 17.1130 +	union irq_ctx *irqctx;
 17.1131 +
 17.1132 +	if (hardirq_ctx[cpu])
 17.1133 +		return;
 17.1134 +
 17.1135 +	irqctx = (union irq_ctx*) &hardirq_stack[cpu*THREAD_SIZE];
 17.1136 +	irqctx->tinfo.task              = NULL;
 17.1137 +	irqctx->tinfo.exec_domain       = NULL;
 17.1138 +	irqctx->tinfo.cpu               = cpu;
 17.1139 +	irqctx->tinfo.preempt_count     = HARDIRQ_OFFSET;
 17.1140 +	irqctx->tinfo.addr_limit        = MAKE_MM_SEG(0);
 17.1141 +
 17.1142 +	hardirq_ctx[cpu] = irqctx;
 17.1143 +
 17.1144 +	irqctx = (union irq_ctx*) &softirq_stack[cpu*THREAD_SIZE];
 17.1145 +	irqctx->tinfo.task              = NULL;
 17.1146 +	irqctx->tinfo.exec_domain       = NULL;
 17.1147 +	irqctx->tinfo.cpu               = cpu;
 17.1148 +	irqctx->tinfo.preempt_count     = SOFTIRQ_OFFSET;
 17.1149 +	irqctx->tinfo.addr_limit        = MAKE_MM_SEG(0);
 17.1150 +
 17.1151 +	softirq_ctx[cpu] = irqctx;
 17.1152 +
 17.1153 +	printk("CPU %u irqstacks, hard=%p soft=%p\n",
 17.1154 +		cpu,hardirq_ctx[cpu],softirq_ctx[cpu]);
 17.1155 +}
 17.1156 +
 17.1157 +extern asmlinkage void __do_softirq(void);
 17.1158 +
 17.1159 +asmlinkage void do_softirq(void)
 17.1160 +{
 17.1161 +	unsigned long flags;
 17.1162 +	struct thread_info *curctx;
 17.1163 +	union irq_ctx *irqctx;
 17.1164 +	u32 *isp;
 17.1165 +
 17.1166 +	if (in_interrupt())
 17.1167 +		return;
 17.1168 +
 17.1169 +	local_irq_save(flags);
 17.1170 +
 17.1171 +	if (local_softirq_pending()) {
 17.1172 +		curctx = current_thread_info();
 17.1173 +		irqctx = softirq_ctx[smp_processor_id()];
 17.1174 +		irqctx->tinfo.task = curctx->task;
 17.1175 +		irqctx->tinfo.previous_esp = current_stack_pointer();
 17.1176 +
 17.1177 +		/* build the stack frame on the softirq stack */
 17.1178 +		isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
 17.1179 +
 17.1180 +
 17.1181 +		asm volatile(
 17.1182 +			"       xchgl   %%ebx,%%esp     \n"
 17.1183 +			"       call    __do_softirq    \n"
 17.1184 +			"       movl    %%ebx,%%esp     \n"
 17.1185 +			: "=b"(isp)
 17.1186 +			: "0"(isp)
 17.1187 +			: "memory", "cc", "edx", "ecx", "eax"
 17.1188 +		);
 17.1189 +	}
 17.1190 +
 17.1191 +	local_irq_restore(flags);
 17.1192 +}
 17.1193 +
 17.1194 +EXPORT_SYMBOL(do_softirq);
 17.1195 +#endif
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c	Wed Jul 14 16:41:41 2004 +0000
    18.3 @@ -0,0 +1,274 @@
    18.4 +/*
    18.5 + * linux/kernel/ldt.c
    18.6 + *
    18.7 + * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
    18.8 + * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
    18.9 + */
   18.10 +
   18.11 +#include <linux/errno.h>
   18.12 +#include <linux/sched.h>
   18.13 +#include <linux/string.h>
   18.14 +#include <linux/mm.h>
   18.15 +#include <linux/smp.h>
   18.16 +#include <linux/smp_lock.h>
   18.17 +#include <linux/vmalloc.h>
   18.18 +#include <linux/slab.h>
   18.19 +
   18.20 +#include <asm/uaccess.h>
   18.21 +#include <asm/system.h>
   18.22 +#include <asm/ldt.h>
   18.23 +#include <asm/desc.h>
   18.24 +
   18.25 +#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
   18.26 +static void flush_ldt(void *null)
   18.27 +{
   18.28 +	if (current->active_mm)
   18.29 +		load_LDT(&current->active_mm->context);
   18.30 +}
   18.31 +#endif
   18.32 +
   18.33 +static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
   18.34 +{
   18.35 +	void *oldldt;
   18.36 +	void *newldt;
   18.37 +	int oldsize;
   18.38 +
   18.39 +	if (mincount <= pc->size)
   18.40 +		return 0;
   18.41 +	oldsize = pc->size;
   18.42 +	mincount = (mincount+511)&(~511);
   18.43 +	if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
   18.44 +		newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
   18.45 +	else
   18.46 +		newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
   18.47 +
   18.48 +	if (!newldt)
   18.49 +		return -ENOMEM;
   18.50 +
   18.51 +	if (oldsize)
   18.52 +		memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
   18.53 +	oldldt = pc->ldt;
   18.54 +	memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
   18.55 +	pc->ldt = newldt;
   18.56 +	wmb();
   18.57 +	pc->size = mincount;
   18.58 +	wmb();
   18.59 +
   18.60 +	if (reload) {
   18.61 +#ifdef CONFIG_SMP
   18.62 +		cpumask_t mask;
   18.63 +		preempt_disable();
   18.64 +#endif
   18.65 +		make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
   18.66 +				    PAGE_SIZE);
   18.67 +		load_LDT(pc);
   18.68 +		flush_page_update_queue();
   18.69 +#ifdef CONFIG_SMP
   18.70 +		mask = cpumask_of_cpu(smp_processor_id());
   18.71 +		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
   18.72 +			smp_call_function(flush_ldt, 0, 1, 1);
   18.73 +		preempt_enable();
   18.74 +#endif
   18.75 +	}
   18.76 +	if (oldsize) {
   18.77 +		if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
   18.78 +			vfree(oldldt);
   18.79 +		else
   18.80 +			kfree(oldldt);
   18.81 +	}
   18.82 +	return 0;
   18.83 +}
   18.84 +
   18.85 +static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
   18.86 +{
   18.87 +	int err = alloc_ldt(new, old->size, 0);
   18.88 +	if (err < 0)
   18.89 +		return err;
   18.90 +	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
   18.91 +	make_pages_readonly(new->ldt, (new->size * LDT_ENTRY_SIZE) /
   18.92 +			    PAGE_SIZE);
   18.93 +	return 0;
   18.94 +}
   18.95 +
   18.96 +/*
   18.97 + * we do not have to muck with descriptors here, that is
   18.98 + * done in switch_mm() as needed.
   18.99 + */
  18.100 +int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
  18.101 +{
  18.102 +	struct mm_struct * old_mm;
  18.103 +	int retval = 0;
  18.104 +
  18.105 +	init_MUTEX(&mm->context.sem);
  18.106 +	mm->context.size = 0;
  18.107 +	old_mm = current->mm;
  18.108 +	if (old_mm && old_mm->context.size > 0) {
  18.109 +		down(&old_mm->context.sem);
  18.110 +		retval = copy_ldt(&mm->context, &old_mm->context);
  18.111 +		up(&old_mm->context.sem);
  18.112 +	}
  18.113 +	return retval;
  18.114 +}
  18.115 +
  18.116 +/*
  18.117 + * No need to lock the MM as we are the last user
  18.118 + */
  18.119 +void destroy_context(struct mm_struct *mm)
  18.120 +{
  18.121 +	if (mm->context.size) {
  18.122 +		if (mm == current->active_mm)
  18.123 +			clear_LDT();
  18.124 +		make_pages_writeable(mm->context.ldt, 
  18.125 +				     (mm->context.size * LDT_ENTRY_SIZE) /
  18.126 +				     PAGE_SIZE);
  18.127 +		flush_page_update_queue();
  18.128 +		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
  18.129 +			vfree(mm->context.ldt);
  18.130 +		else
  18.131 +			kfree(mm->context.ldt);
  18.132 +		mm->context.size = 0;
  18.133 +	}
  18.134 +}
  18.135 +
  18.136 +static int read_ldt(void __user * ptr, unsigned long bytecount)
  18.137 +{
  18.138 +	int err;
  18.139 +	unsigned long size;
  18.140 +	struct mm_struct * mm = current->mm;
  18.141 +
  18.142 +	if (!mm->context.size)
  18.143 +		return 0;
  18.144 +	if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
  18.145 +		bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
  18.146 +
  18.147 +	down(&mm->context.sem);
  18.148 +	size = mm->context.size*LDT_ENTRY_SIZE;
  18.149 +	if (size > bytecount)
  18.150 +		size = bytecount;
  18.151 +
  18.152 +	err = 0;
  18.153 +	if (copy_to_user(ptr, mm->context.ldt, size))
  18.154 +		err = -EFAULT;
  18.155 +	up(&mm->context.sem);
  18.156 +	if (err < 0)
  18.157 +		return err;
  18.158 +	if (size != bytecount) {
  18.159 +		/* zero-fill the rest */
  18.160 +		clear_user(ptr+size, bytecount-size);
  18.161 +	}
  18.162 +	return bytecount;
  18.163 +}
  18.164 +
  18.165 +static int read_default_ldt(void __user * ptr, unsigned long bytecount)
  18.166 +{
  18.167 +	int err;
  18.168 +	unsigned long size;
  18.169 +	void *address;
  18.170 +
  18.171 +	err = 0;
  18.172 +	address = &default_ldt[0];
  18.173 +	size = 5*sizeof(struct desc_struct);
  18.174 +	if (size > bytecount)
  18.175 +		size = bytecount;
  18.176 +
  18.177 +	err = size;
  18.178 +	if (copy_to_user(ptr, address, size))
  18.179 +		err = -EFAULT;
  18.180 +
  18.181 +	return err;
  18.182 +}
  18.183 +
  18.184 +static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
  18.185 +{
  18.186 +	struct mm_struct * mm = current->mm;
  18.187 +	__u32 entry_1, entry_2, *lp;
  18.188 +	unsigned long phys_lp, max_limit;
  18.189 +	int error;
  18.190 +	struct user_desc ldt_info;
  18.191 +
  18.192 +	error = -EINVAL;
  18.193 +	if (bytecount != sizeof(ldt_info))
  18.194 +		goto out;
  18.195 +	error = -EFAULT; 	
  18.196 +	if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
  18.197 +		goto out;
  18.198 +
  18.199 +	error = -EINVAL;
  18.200 +	if (ldt_info.entry_number >= LDT_ENTRIES)
  18.201 +		goto out;
  18.202 +	if (ldt_info.contents == 3) {
  18.203 +		if (oldmode)
  18.204 +			goto out;
  18.205 +		if (ldt_info.seg_not_present == 0)
  18.206 +			goto out;
  18.207 +	}
  18.208 +
  18.209 +	/*
  18.210 +	 * This makes our tests for overlap with Xen space
  18.211 +	 * easier. There's no good reason to have a user segment
  18.212 +	 * starting this high anyway.
  18.213 +	 */
  18.214 +	if (ldt_info.base_addr >= PAGE_OFFSET)
  18.215 +		goto out;
  18.216 +
  18.217 +	down(&mm->context.sem);
  18.218 +	if (ldt_info.entry_number >= mm->context.size) {
  18.219 +		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
  18.220 +		if (error < 0)
  18.221 +			goto out_unlock;
  18.222 +	}
  18.223 +
  18.224 +	lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
  18.225 +	phys_lp = arbitrary_virt_to_phys(lp);
  18.226 +
  18.227 +   	/* Allow LDTs to be cleared by the user. */
  18.228 +   	if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
  18.229 +		if (oldmode || LDT_empty(&ldt_info)) {
  18.230 +			entry_1 = 0;
  18.231 +			entry_2 = 0;
  18.232 +			goto install;
  18.233 +		}
  18.234 +	}
  18.235 +
  18.236 +	max_limit = HYPERVISOR_VIRT_START - ldt_info.base_addr;
  18.237 +	if (ldt_info.limit_in_pages)
  18.238 +		max_limit >>= PAGE_SHIFT;
  18.239 +	max_limit--;
  18.240 +	if ((ldt_info.limit & 0xfffff) > (max_limit & 0xfffff))
  18.241 +		ldt_info.limit = max_limit;
  18.242 +
  18.243 +	entry_1 = LDT_entry_a(&ldt_info);
  18.244 +	entry_2 = LDT_entry_b(&ldt_info);
  18.245 +	if (oldmode)
  18.246 +		entry_2 &= ~(1 << 20);
  18.247 +
  18.248 +	/* Install the new entry ...  */
  18.249 +install:
  18.250 +	error = HYPERVISOR_update_descriptor(phys_lp, entry_1, entry_2);
  18.251 +
  18.252 +out_unlock:
  18.253 +	up(&mm->context.sem);
  18.254 +out:
  18.255 +	return error;
  18.256 +}
  18.257 +
  18.258 +asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
  18.259 +{
  18.260 +	int ret = -ENOSYS;
  18.261 +
  18.262 +	switch (func) {
  18.263 +	case 0:
  18.264 +		ret = read_ldt(ptr, bytecount);
  18.265 +		break;
  18.266 +	case 1:
  18.267 +		ret = write_ldt(ptr, bytecount, 1);
  18.268 +		break;
  18.269 +	case 2:
  18.270 +		ret = read_default_ldt(ptr, bytecount);
  18.271 +		break;
  18.272 +	case 0x11:
  18.273 +		ret = write_ldt(ptr, bytecount, 0);
  18.274 +		break;
  18.275 +	}
  18.276 +	return ret;
  18.277 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c	Wed Jul 14 16:41:41 2004 +0000
    19.3 @@ -0,0 +1,782 @@
    19.4 +/*
    19.5 + *  linux/arch/i386/kernel/process.c
    19.6 + *
    19.7 + *  Copyright (C) 1995  Linus Torvalds
    19.8 + *
    19.9 + *  Pentium III FXSR, SSE support
   19.10 + *	Gareth Hughes <gareth@valinux.com>, May 2000
   19.11 + */
   19.12 +
   19.13 +/*
   19.14 + * This file handles the architecture-dependent parts of process handling..
   19.15 + */
   19.16 +
   19.17 +#include <stdarg.h>
   19.18 +
   19.19 +#include <linux/errno.h>
   19.20 +#include <linux/sched.h>
   19.21 +#include <linux/fs.h>
   19.22 +#include <linux/kernel.h>
   19.23 +#include <linux/mm.h>
   19.24 +#include <linux/elfcore.h>
   19.25 +#include <linux/smp.h>
   19.26 +#include <linux/smp_lock.h>
   19.27 +#include <linux/stddef.h>
   19.28 +#include <linux/slab.h>
   19.29 +#include <linux/vmalloc.h>
   19.30 +#include <linux/user.h>
   19.31 +#include <linux/a.out.h>
   19.32 +#include <linux/interrupt.h>
   19.33 +#include <linux/config.h>
   19.34 +#include <linux/version.h>
   19.35 +#include <linux/delay.h>
   19.36 +#include <linux/reboot.h>
   19.37 +#include <linux/init.h>
   19.38 +#include <linux/mc146818rtc.h>
   19.39 +#include <linux/module.h>
   19.40 +#include <linux/kallsyms.h>
   19.41 +#include <linux/ptrace.h>
   19.42 +
   19.43 +#include <asm/uaccess.h>
   19.44 +#include <asm/pgtable.h>
   19.45 +#include <asm/system.h>
   19.46 +#include <asm/io.h>
   19.47 +#include <asm/ldt.h>
   19.48 +#include <asm/processor.h>
   19.49 +#include <asm/i387.h>
   19.50 +#include <asm/irq.h>
   19.51 +#include <asm/desc.h>
   19.52 +#ifdef CONFIG_MATH_EMULATION
   19.53 +#include <asm/math_emu.h>
   19.54 +#endif
   19.55 +
   19.56 +#include <linux/irq.h>
   19.57 +#include <linux/err.h>
   19.58 +
   19.59 +asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
   19.60 +
   19.61 +int hlt_counter;
   19.62 +
   19.63 +/*
   19.64 + * Return saved PC of a blocked thread.
   19.65 + */
   19.66 +unsigned long thread_saved_pc(struct task_struct *tsk)
   19.67 +{
   19.68 +	return ((unsigned long *)tsk->thread.esp)[3];
   19.69 +}
   19.70 +
   19.71 +/*
   19.72 + * Powermanagement idle function, if any..
   19.73 + */
   19.74 +void (*pm_idle)(void);
   19.75 +
   19.76 +void disable_hlt(void)
   19.77 +{
   19.78 +	hlt_counter++;
   19.79 +}
   19.80 +
   19.81 +EXPORT_SYMBOL(disable_hlt);
   19.82 +
   19.83 +void enable_hlt(void)
   19.84 +{
   19.85 +	hlt_counter--;
   19.86 +}
   19.87 +
   19.88 +EXPORT_SYMBOL(enable_hlt);
   19.89 +
   19.90 +/*
   19.91 + * We use this if we don't have any better
   19.92 + * idle routine..
   19.93 + */
   19.94 +void default_idle(void)
   19.95 +{
   19.96 +	if (!hlt_counter && current_cpu_data.hlt_works_ok) {
   19.97 +		local_irq_disable();
   19.98 +		if (!need_resched())
   19.99 +			safe_halt();
  19.100 +		else
  19.101 +			local_irq_enable();
  19.102 +	}
  19.103 +}
  19.104 +
  19.105 +/*
  19.106 + * On SMP it's slightly faster (but much more power-consuming!)
  19.107 + * to poll the ->work.need_resched flag instead of waiting for the
  19.108 + * cross-CPU IPI to arrive. Use this option with caution.
  19.109 + */
  19.110 +static void poll_idle (void)
  19.111 +{
  19.112 +	int oldval;
  19.113 +
  19.114 +	local_irq_enable();
  19.115 +
  19.116 +	/*
  19.117 +	 * Deal with another CPU just having chosen a thread to
  19.118 +	 * run here:
  19.119 +	 */
  19.120 +	oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
  19.121 +
  19.122 +	if (!oldval) {
  19.123 +		set_thread_flag(TIF_POLLING_NRFLAG);
  19.124 +		asm volatile(
  19.125 +			"2:"
  19.126 +			"testl %0, %1;"
  19.127 +			"rep; nop;"
  19.128 +			"je 2b;"
  19.129 +			: : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
  19.130 +
  19.131 +		clear_thread_flag(TIF_POLLING_NRFLAG);
  19.132 +	} else {
  19.133 +		set_need_resched();
  19.134 +	}
  19.135 +}
  19.136 +
  19.137 +/*
  19.138 + * The idle thread. There's no useful work to be
  19.139 + * done, so just try to conserve power and have a
  19.140 + * low exit latency (ie sit in a loop waiting for
  19.141 + * somebody to say that they'd like to reschedule)
  19.142 + */
  19.143 +void cpu_idle (void)
  19.144 +{
  19.145 +	/* endless idle loop with no priority at all */
  19.146 +	while (1) {
  19.147 +		while (!need_resched()) {
  19.148 +			void (*idle)(void) = pm_idle;
  19.149 +
  19.150 +			if (!idle)
  19.151 +				idle = default_idle;
  19.152 +
  19.153 +			irq_stat[smp_processor_id()].idle_timestamp = jiffies;
  19.154 +			idle();
  19.155 +		}
  19.156 +		schedule();
  19.157 +	}
  19.158 +}
  19.159 +
  19.160 +/*
  19.161 + * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
  19.162 + * which can obviate IPI to trigger checking of need_resched.
  19.163 + * We execute MONITOR against need_resched and enter optimized wait state
  19.164 + * through MWAIT. Whenever someone changes need_resched, we would be woken
  19.165 + * up from MWAIT (without an IPI).
  19.166 + */
  19.167 +static void mwait_idle(void)
  19.168 +{
  19.169 +	local_irq_enable();
  19.170 +
  19.171 +	if (!need_resched()) {
  19.172 +		set_thread_flag(TIF_POLLING_NRFLAG);
  19.173 +		do {
  19.174 +			__monitor((void *)&current_thread_info()->flags, 0, 0);
  19.175 +			if (need_resched())
  19.176 +				break;
  19.177 +			__mwait(0, 0);
  19.178 +		} while (!need_resched());
  19.179 +		clear_thread_flag(TIF_POLLING_NRFLAG);
  19.180 +	}
  19.181 +}
  19.182 +
  19.183 +void __init select_idle_routine(const struct cpuinfo_x86 *c)
  19.184 +{
  19.185 +	if (cpu_has(c, X86_FEATURE_MWAIT)) {
  19.186 +		printk("monitor/mwait feature present.\n");
  19.187 +		/*
  19.188 +		 * Skip, if setup has overridden idle.
  19.189 +		 * Also, take care of system with asymmetric CPUs.
  19.190 +		 * Use, mwait_idle only if all cpus support it.
  19.191 +		 * If not, we fallback to default_idle()
  19.192 +		 */
  19.193 +		if (!pm_idle) {
  19.194 +			printk("using mwait in idle threads.\n");
  19.195 +			pm_idle = mwait_idle;
  19.196 +		}
  19.197 +		return;
  19.198 +	}
  19.199 +	pm_idle = xen_cpu_idle;
  19.200 +	return;
  19.201 +}
  19.202 +
  19.203 +static int __init idle_setup (char *str)
  19.204 +{
  19.205 +	if (!strncmp(str, "poll", 4)) {
  19.206 +		printk("using polling idle threads.\n");
  19.207 +		pm_idle = poll_idle;
  19.208 +#ifdef CONFIG_X86_SMP
  19.209 +		if (smp_num_siblings > 1)
  19.210 +			printk("WARNING: polling idle and HT enabled, performance may degrade.\n");
  19.211 +#endif
  19.212 +	} else if (!strncmp(str, "halt", 4)) {
  19.213 +		printk("using halt in idle threads.\n");
  19.214 +		pm_idle = default_idle;
  19.215 +	}
  19.216 +
  19.217 +	return 1;
  19.218 +}
  19.219 +
  19.220 +__setup("idle=", idle_setup);
  19.221 +
  19.222 +void show_regs(struct pt_regs * regs)
  19.223 +{
  19.224 +	printk("\n");
  19.225 +	printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
  19.226 +	printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
  19.227 +	print_symbol("EIP is at %s\n", regs->eip);
  19.228 +
  19.229 +	if (regs->xcs & 2)
  19.230 +		printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
  19.231 +	printk(" EFLAGS: %08lx    %s  (%s)\n",regs->eflags, print_tainted(),UTS_RELEASE);
  19.232 +	printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
  19.233 +		regs->eax,regs->ebx,regs->ecx,regs->edx);
  19.234 +	printk("ESI: %08lx EDI: %08lx EBP: %08lx",
  19.235 +		regs->esi, regs->edi, regs->ebp);
  19.236 +	printk(" DS: %04x ES: %04x\n",
  19.237 +		0xffff & regs->xds,0xffff & regs->xes);
  19.238 +
  19.239 +	show_trace(NULL, &regs->esp);
  19.240 +}
  19.241 +
  19.242 +/*
  19.243 + * This gets run with %ebx containing the
  19.244 + * function to call, and %edx containing
  19.245 + * the "args".
  19.246 + */
  19.247 +extern void kernel_thread_helper(void);
  19.248 +__asm__(".section .text\n"
  19.249 +	".align 4\n"
  19.250 +	"kernel_thread_helper:\n\t"
  19.251 +	"movl %edx,%eax\n\t"
  19.252 +	"pushl %edx\n\t"
  19.253 +	"call *%ebx\n\t"
  19.254 +	"pushl %eax\n\t"
  19.255 +	"call do_exit\n"
  19.256 +	".previous");
  19.257 +
  19.258 +/*
  19.259 + * Create a kernel thread
  19.260 + */
  19.261 +int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
  19.262 +{
  19.263 +	struct pt_regs regs;
  19.264 +
  19.265 +	memset(&regs, 0, sizeof(regs));
  19.266 +
  19.267 +	regs.ebx = (unsigned long) fn;
  19.268 +	regs.edx = (unsigned long) arg;
  19.269 +
  19.270 +	regs.xds = __USER_DS;
  19.271 +	regs.xes = __USER_DS;
  19.272 +	regs.orig_eax = -1;
  19.273 +	regs.eip = (unsigned long) kernel_thread_helper;
  19.274 +	regs.xcs = __KERNEL_CS;
  19.275 +	regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
  19.276 +
  19.277 +	/* Ok, create the new process.. */
  19.278 +	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
  19.279 +}
  19.280 +
  19.281 +/*
  19.282 + * Free current thread data structures etc..
  19.283 + */
  19.284 +void exit_thread(void)
  19.285 +{
  19.286 +	struct task_struct *tsk = current;
  19.287 +
  19.288 +	/* The process may have allocated an io port bitmap... nuke it. */
  19.289 +	if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) {
  19.290 +		int cpu = get_cpu();
  19.291 +		struct tss_struct *tss = init_tss + cpu;
  19.292 +		kfree(tsk->thread.io_bitmap_ptr);
  19.293 +		tsk->thread.io_bitmap_ptr = NULL;
  19.294 +		tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
  19.295 +		put_cpu();
  19.296 +	}
  19.297 +}
  19.298 +
  19.299 +void flush_thread(void)
  19.300 +{
  19.301 +	struct task_struct *tsk = current;
  19.302 +
  19.303 +	memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
  19.304 +	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));	
  19.305 +	/*
  19.306 +	 * Forget coprocessor state..
  19.307 +	 */
  19.308 +	clear_fpu(tsk);
  19.309 +	tsk->used_math = 0;
  19.310 +}
  19.311 +
  19.312 +void release_thread(struct task_struct *dead_task)
  19.313 +{
  19.314 +	if (dead_task->mm) {
  19.315 +		// temporary debugging check
  19.316 +		if (dead_task->mm->context.size) {
  19.317 +			printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
  19.318 +					dead_task->comm,
  19.319 +					dead_task->mm->context.ldt,
  19.320 +					dead_task->mm->context.size);
  19.321 +			BUG();
  19.322 +		}
  19.323 +	}
  19.324 +
  19.325 +	release_x86_irqs(dead_task);
  19.326 +}
  19.327 +
  19.328 +/*
  19.329 + * This gets called before we allocate a new thread and copy
  19.330 + * the current task into it.
  19.331 + */
  19.332 +void prepare_to_copy(struct task_struct *tsk)
  19.333 +{
  19.334 +	unlazy_fpu(tsk);
  19.335 +}
  19.336 +
  19.337 +int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
  19.338 +	unsigned long unused,
  19.339 +	struct task_struct * p, struct pt_regs * regs)
  19.340 +{
  19.341 +	struct pt_regs * childregs;
  19.342 +	struct task_struct *tsk;
  19.343 +	int err;
  19.344 +
  19.345 +	childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
  19.346 +	struct_cpy(childregs, regs);
  19.347 +	childregs->eax = 0;
  19.348 +	childregs->esp = esp;
  19.349 +	p->set_child_tid = p->clear_child_tid = NULL;
  19.350 +
  19.351 +	p->thread.esp = (unsigned long) childregs;
  19.352 +	p->thread.esp0 = (unsigned long) (childregs+1);
  19.353 +
  19.354 +	p->thread.eip = (unsigned long) ret_from_fork;
  19.355 +
  19.356 +	savesegment(fs,p->thread.fs);
  19.357 +	savesegment(gs,p->thread.gs);
  19.358 +
  19.359 +	tsk = current;
  19.360 +	if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) {
  19.361 +		p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
  19.362 +		if (!p->thread.io_bitmap_ptr)
  19.363 +			return -ENOMEM;
  19.364 +		memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr,
  19.365 +			IO_BITMAP_BYTES);
  19.366 +	}
  19.367 +
  19.368 +	/*
  19.369 +	 * Set a new TLS for the child thread?
  19.370 +	 */
  19.371 +	if (clone_flags & CLONE_SETTLS) {
  19.372 +		struct desc_struct *desc;
  19.373 +		struct user_desc info;
  19.374 +		int idx;
  19.375 +
  19.376 +		err = -EFAULT;
  19.377 +		if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info)))
  19.378 +			goto out;
  19.379 +		err = -EINVAL;
  19.380 +		if (LDT_empty(&info))
  19.381 +			goto out;
  19.382 +
  19.383 +		idx = info.entry_number;
  19.384 +		if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
  19.385 +			goto out;
  19.386 +
  19.387 +		desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
  19.388 +		desc->a = LDT_entry_a(&info);
  19.389 +		desc->b = LDT_entry_b(&info);
  19.390 +	}
  19.391 +
  19.392 +	err = 0;
  19.393 + out:
  19.394 +	if (err && p->thread.io_bitmap_ptr)
  19.395 +		kfree(p->thread.io_bitmap_ptr);
  19.396 +	return err;
  19.397 +}
  19.398 +
  19.399 +/*
  19.400 + * fill in the user structure for a core dump..
  19.401 + */
  19.402 +void dump_thread(struct pt_regs * regs, struct user * dump)
  19.403 +{
  19.404 +	int i;
  19.405 +
  19.406 +/* changed the size calculations - should hopefully work better. lbt */
  19.407 +	dump->magic = CMAGIC;
  19.408 +	dump->start_code = 0;
  19.409 +	dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
  19.410 +	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
  19.411 +	dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
  19.412 +	dump->u_dsize -= dump->u_tsize;
  19.413 +	dump->u_ssize = 0;
  19.414 +	for (i = 0; i < 8; i++)
  19.415 +		dump->u_debugreg[i] = current->thread.debugreg[i];  
  19.416 +
  19.417 +	if (dump->start_stack < TASK_SIZE)
  19.418 +		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
  19.419 +
  19.420 +	dump->regs.ebx = regs->ebx;
  19.421 +	dump->regs.ecx = regs->ecx;
  19.422 +	dump->regs.edx = regs->edx;
  19.423 +	dump->regs.esi = regs->esi;
  19.424 +	dump->regs.edi = regs->edi;
  19.425 +	dump->regs.ebp = regs->ebp;
  19.426 +	dump->regs.eax = regs->eax;
  19.427 +	dump->regs.ds = regs->xds;
  19.428 +	dump->regs.es = regs->xes;
  19.429 +	savesegment(fs,dump->regs.fs);
  19.430 +	savesegment(gs,dump->regs.gs);
  19.431 +	dump->regs.orig_eax = regs->orig_eax;
  19.432 +	dump->regs.eip = regs->eip;
  19.433 +	dump->regs.cs = regs->xcs;
  19.434 +	dump->regs.eflags = regs->eflags;
  19.435 +	dump->regs.esp = regs->esp;
  19.436 +	dump->regs.ss = regs->xss;
  19.437 +
  19.438 +	dump->u_fpvalid = dump_fpu (regs, &dump->i387);
  19.439 +}
  19.440 +
  19.441 +/* 
  19.442 + * Capture the user space registers if the task is not running (in user space)
  19.443 + */
  19.444 +int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
  19.445 +{
  19.446 +	struct pt_regs ptregs;
  19.447 +	
  19.448 +	ptregs = *(struct pt_regs *)
  19.449 +		((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs));
  19.450 +	ptregs.xcs &= 0xffff;
  19.451 +	ptregs.xds &= 0xffff;
  19.452 +	ptregs.xes &= 0xffff;
  19.453 +	ptregs.xss &= 0xffff;
  19.454 +
  19.455 +	elf_core_copy_regs(regs, &ptregs);
  19.456 +
  19.457 +	return 1;
  19.458 +}
  19.459 +
  19.460 +/*
  19.461 + * This special macro can be used to load a debugging register
  19.462 + */
  19.463 +#define loaddebug(thread,register) \
  19.464 +		HYPERVISOR_set_debugreg((register),	\
  19.465 +			(thread->debugreg[register]))
  19.466 +
  19.467 +/*
  19.468 + *	switch_to(x,yn) should switch tasks from x to y.
  19.469 + *
  19.470 + * We fsave/fwait so that an exception goes off at the right time
  19.471 + * (as a call from the fsave or fwait in effect) rather than to
  19.472 + * the wrong process. Lazy FP saving no longer makes any sense
  19.473 + * with modern CPU's, and this simplifies a lot of things (SMP
  19.474 + * and UP become the same).
  19.475 + *
  19.476 + * NOTE! We used to use the x86 hardware context switching. The
  19.477 + * reason for not using it any more becomes apparent when you
  19.478 + * try to recover gracefully from saved state that is no longer
  19.479 + * valid (stale segment register values in particular). With the
  19.480 + * hardware task-switch, there is no way to fix up bad state in
  19.481 + * a reasonable manner.
  19.482 + *
  19.483 + * The fact that Intel documents the hardware task-switching to
  19.484 + * be slow is a fairly red herring - this code is not noticeably
  19.485 + * faster. However, there _is_ some room for improvement here,
  19.486 + * so the performance issues may eventually be a valid point.
  19.487 + * More important, however, is the fact that this allows us much
  19.488 + * more flexibility.
  19.489 + *
  19.490 + * The return value (in %eax) will be the "prev" task after
  19.491 + * the task-switch, and shows up in ret_from_fork in entry.S,
  19.492 + * for example.
  19.493 + */
  19.494 +struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
  19.495 +{
  19.496 +	struct thread_struct *prev = &prev_p->thread,
  19.497 +				 *next = &next_p->thread;
  19.498 +	int cpu = smp_processor_id();
  19.499 +	struct tss_struct *tss = init_tss + cpu;
  19.500 +	unsigned long flags;
  19.501 +
  19.502 +	local_irq_save(flags);
  19.503 +
  19.504 +	/*
  19.505 +	 * Save away %fs and %gs. No need to save %es and %ds, as
  19.506 +	 * those are always kernel segments while inside the kernel.
  19.507 +	 */
  19.508 +	asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->fs));
  19.509 +	asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs));
  19.510 +
  19.511 +	/*
  19.512 +	 * We clobber FS and GS here so that we avoid a GPF when
  19.513 +	 * restoring previous task's FS/GS values in Xen when the LDT
  19.514 +	 * is switched. If we don't do this then we can end up
  19.515 +	 * erroneously re-flushing the page-update queue when we
  19.516 +	 * 'execute_multicall_list'.
  19.517 +	 */
  19.518 +	__asm__ __volatile__ ( 
  19.519 +		"xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs" : : :
  19.520 +		"eax" );
  19.521 +
  19.522 +	flush_page_update_queue();
  19.523 +
  19.524 +	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
  19.525 +
  19.526 +	__unlazy_fpu(prev_p);
  19.527 +
  19.528 +	/*
  19.529 +	 * Reload esp0, LDT and the page table pointer:
  19.530 +	 */
  19.531 +	load_esp0(tss, next);
  19.532 +
  19.533 +	/*
  19.534 +	 * Load the per-thread Thread-Local Storage descriptor.
  19.535 +	 */
  19.536 +	load_TLS(next, cpu);
  19.537 +
  19.538 +	local_irq_restore(flags);
  19.539 +
  19.540 +	/*
  19.541 +	 * Restore %fs and %gs if needed.
  19.542 +	 */
  19.543 +	if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) {
  19.544 +		loadsegment(fs, next->fs);
  19.545 +		loadsegment(gs, next->gs);
  19.546 +	}
  19.547 +
  19.548 +	/*
  19.549 +	 * Now maybe reload the debug registers
  19.550 +	 */
  19.551 +	if (unlikely(next->debugreg[7])) {
  19.552 +		loaddebug(next, 0);
  19.553 +		loaddebug(next, 1);
  19.554 +		loaddebug(next, 2);
  19.555 +		loaddebug(next, 3);
  19.556 +		/* no 4 and 5 */
  19.557 +		loaddebug(next, 6);
  19.558 +		loaddebug(next, 7);
  19.559 +	}
  19.560 +
  19.561 +	if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
  19.562 +		if (next->io_bitmap_ptr) {
  19.563 +			/*
  19.564 +			 * 4 cachelines copy ... not good, but not that
  19.565 +			 * bad either. Anyone got something better?
  19.566 +			 * This only affects processes which use ioperm().
  19.567 +			 * [Putting the TSSs into 4k-tlb mapped regions
  19.568 +			 * and playing VM tricks to switch the IO bitmap
  19.569 +			 * is not really acceptable.]
  19.570 +			 */
  19.571 +			memcpy(tss->io_bitmap, next->io_bitmap_ptr,
  19.572 +				IO_BITMAP_BYTES);
  19.573 +			tss->io_bitmap_base = IO_BITMAP_OFFSET;
  19.574 +		} else
  19.575 +			/*
  19.576 +			 * a bitmap offset pointing outside of the TSS limit
  19.577 +			 * causes a nicely controllable SIGSEGV if a process
  19.578 +			 * tries to use a port IO instruction. The first
  19.579 +			 * sys_ioperm() call sets up the bitmap properly.
  19.580 +			 */
  19.581 +			tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
  19.582 +	}
  19.583 +	return prev_p;
  19.584 +}
  19.585 +
  19.586 +asmlinkage int sys_fork(struct pt_regs regs)
  19.587 +{
  19.588 +	return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
  19.589 +}
  19.590 +
  19.591 +asmlinkage int sys_clone(struct pt_regs regs)
  19.592 +{
  19.593 +	unsigned long clone_flags;
  19.594 +	unsigned long newsp;
  19.595 +	int __user *parent_tidptr, *child_tidptr;
  19.596 +
  19.597 +	clone_flags = regs.ebx;
  19.598 +	newsp = regs.ecx;
  19.599 +	parent_tidptr = (int __user *)regs.edx;
  19.600 +	child_tidptr = (int __user *)regs.edi;
  19.601 +	if (!newsp)
  19.602 +		newsp = regs.esp;
  19.603 +	return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, parent_tidptr, child_tidptr);
  19.604 +}
  19.605 +
  19.606 +/*
  19.607 + * This is trivial, and on the face of it looks like it
  19.608 + * could equally well be done in user mode.
  19.609 + *
  19.610 + * Not so, for quite unobvious reasons - register pressure.
  19.611 + * In user mode vfork() cannot have a stack frame, and if
  19.612 + * done by calling the "clone()" system call directly, you
  19.613 + * do not have enough call-clobbered registers to hold all
  19.614 + * the information you need.
  19.615 + */
  19.616 +asmlinkage int sys_vfork(struct pt_regs regs)
  19.617 +{
  19.618 +	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
  19.619 +}
  19.620 +
  19.621 +/*
  19.622 + * sys_execve() executes a new program.
  19.623 + */
  19.624 +asmlinkage int sys_execve(struct pt_regs regs)
  19.625 +{
  19.626 +	int error;
  19.627 +	char * filename;
  19.628 +
  19.629 +	filename = getname((char __user *) regs.ebx);
  19.630 +	error = PTR_ERR(filename);
  19.631 +	if (IS_ERR(filename))
  19.632 +		goto out;
  19.633 +	error = do_execve(filename,
  19.634 +			(char __user * __user *) regs.ecx,
  19.635 +			(char __user * __user *) regs.edx,
  19.636 +			&regs);
  19.637 +	if (error == 0) {
  19.638 +		current->ptrace &= ~PT_DTRACE;
  19.639 +		/* Make sure we don't return using sysenter.. */
  19.640 +		set_thread_flag(TIF_IRET);
  19.641 +	}
  19.642 +	putname(filename);
  19.643 +out:
  19.644 +	return error;
  19.645 +}
  19.646 +
  19.647 +#define top_esp                (THREAD_SIZE - sizeof(unsigned long))
  19.648 +#define top_ebp                (THREAD_SIZE - 2*sizeof(unsigned long))
  19.649 +
  19.650 +unsigned long get_wchan(struct task_struct *p)
  19.651 +{
  19.652 +	unsigned long ebp, esp, eip;
  19.653 +	unsigned long stack_page;
  19.654 +	int count = 0;
  19.655 +	if (!p || p == current || p->state == TASK_RUNNING)
  19.656 +		return 0;
  19.657 +	stack_page = (unsigned long)p->thread_info;
  19.658 +	esp = p->thread.esp;
  19.659 +	if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
  19.660 +		return 0;
  19.661 +	/* include/asm-i386/system.h:switch_to() pushes ebp last. */
  19.662 +	ebp = *(unsigned long *) esp;
  19.663 +	do {
  19.664 +		if (ebp < stack_page || ebp > top_ebp+stack_page)
  19.665 +			return 0;
  19.666 +		eip = *(unsigned long *) (ebp+4);
  19.667 +		if (!in_sched_functions(eip))
  19.668 +			return eip;
  19.669 +		ebp = *(unsigned long *) ebp;
  19.670 +	} while (count++ < 16);
  19.671 +	return 0;
  19.672 +}
  19.673 +
  19.674 +/*
  19.675 + * sys_alloc_thread_area: get a yet unused TLS descriptor index.
  19.676 + */
  19.677 +static int get_free_idx(void)
  19.678 +{
  19.679 +	struct thread_struct *t = &current->thread;
  19.680 +	int idx;
  19.681 +
  19.682 +	for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
  19.683 +		if (desc_empty(t->tls_array + idx))
  19.684 +			return idx + GDT_ENTRY_TLS_MIN;
  19.685 +	return -ESRCH;
  19.686 +}
  19.687 +
  19.688 +/*
  19.689 + * Set a given TLS descriptor:
  19.690 + */
  19.691 +asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
  19.692 +{
  19.693 +	struct thread_struct *t = &current->thread;
  19.694 +	struct user_desc info;
  19.695 +	struct desc_struct *desc;
  19.696 +	int cpu, idx;
  19.697 +
  19.698 +	if (copy_from_user(&info, u_info, sizeof(info)))
  19.699 +		return -EFAULT;
  19.700 +	idx = info.entry_number;
  19.701 +
  19.702 +	/*
  19.703 +	 * index -1 means the kernel should try to find and
  19.704 +	 * allocate an empty descriptor:
  19.705 +	 */
  19.706 +	if (idx == -1) {
  19.707 +		idx = get_free_idx();
  19.708 +		if (idx < 0)
  19.709 +			return idx;
  19.710 +		if (put_user(idx, &u_info->entry_number))
  19.711 +			return -EFAULT;
  19.712 +	}
  19.713 +
  19.714 +	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
  19.715 +		return -EINVAL;
  19.716 +
  19.717 +	desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
  19.718 +
  19.719 +	/*
  19.720 +	 * We must not get preempted while modifying the TLS.
  19.721 +	 */
  19.722 +	cpu = get_cpu();
  19.723 +
  19.724 +	if (LDT_empty(&info)) {
  19.725 +		desc->a = 0;
  19.726 +		desc->b = 0;
  19.727 +	} else {
  19.728 +		desc->a = LDT_entry_a(&info);
  19.729 +		desc->b = LDT_entry_b(&info);
  19.730 +	}
  19.731 +	load_TLS(t, cpu);
  19.732 +
  19.733 +	put_cpu();
  19.734 +
  19.735 +	return 0;
  19.736 +}
  19.737 +
  19.738 +/*
  19.739 + * Get the current Thread-Local Storage area:
  19.740 + */
  19.741 +
  19.742 +#define GET_BASE(desc) ( \
  19.743 +	(((desc)->a >> 16) & 0x0000ffff) | \
  19.744 +	(((desc)->b << 16) & 0x00ff0000) | \
  19.745 +	( (desc)->b        & 0xff000000)   )
  19.746 +
  19.747 +#define GET_LIMIT(desc) ( \
  19.748 +	((desc)->a & 0x0ffff) | \
  19.749 +	 ((desc)->b & 0xf0000) )
  19.750 +	
  19.751 +#define GET_32BIT(desc)		(((desc)->b >> 22) & 1)
  19.752 +#define GET_CONTENTS(desc)	(((desc)->b >> 10) & 3)
  19.753 +#define GET_WRITABLE(desc)	(((desc)->b >>  9) & 1)
  19.754 +#define GET_LIMIT_PAGES(desc)	(((desc)->b >> 23) & 1)
  19.755 +#define GET_PRESENT(desc)	(((desc)->b >> 15) & 1)
  19.756 +#define GET_USEABLE(desc)	(((desc)->b >> 20) & 1)
  19.757 +
  19.758 +asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
  19.759 +{
  19.760 +	struct user_desc info;
  19.761 +	struct desc_struct *desc;
  19.762 +	int idx;
  19.763 +
  19.764 +	if (get_user(idx, &u_info->entry_number))
  19.765 +		return -EFAULT;
  19.766 +	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
  19.767 +		return -EINVAL;
  19.768 +
  19.769 +	desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
  19.770 +
  19.771 +	info.entry_number = idx;
  19.772 +	info.base_addr = GET_BASE(desc);
  19.773 +	info.limit = GET_LIMIT(desc);
  19.774 +	info.seg_32bit = GET_32BIT(desc);
  19.775 +	info.contents = GET_CONTENTS(desc);
  19.776 +	info.read_exec_only = !GET_WRITABLE(desc);
  19.777 +	info.limit_in_pages = GET_LIMIT_PAGES(desc);
  19.778 +	info.seg_not_present = !GET_PRESENT(desc);
  19.779 +	info.useable = GET_USEABLE(desc);
  19.780 +
  19.781 +	if (copy_to_user(u_info, &info, sizeof(info)))
  19.782 +		return -EFAULT;
  19.783 +	return 0;
  19.784 +}
  19.785 +
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c	Wed Jul 14 16:41:41 2004 +0000
    20.3 @@ -0,0 +1,1218 @@
    20.4 +/*
    20.5 + *  linux/arch/i386/kernel/setup.c
    20.6 + *
    20.7 + *  Copyright (C) 1995  Linus Torvalds
    20.8 + *
    20.9 + *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
   20.10 + *
   20.11 + *  Memory region support
   20.12 + *	David Parsons <orc@pell.chi.il.us>, July-August 1999
   20.13 + *
   20.14 + *  Added E820 sanitization routine (removes overlapping memory regions);
   20.15 + *  Brian Moyle <bmoyle@mvista.com>, February 2001
   20.16 + *
   20.17 + * Moved CPU detection code to cpu/${cpu}.c
   20.18 + *    Patrick Mochel <mochel@osdl.org>, March 2002
   20.19 + *
   20.20 + *  Provisions for empty E820 memory regions (reported by certain BIOSes).
   20.21 + *  Alex Achenbach <xela@slit.de>, December 2002.
   20.22 + *
   20.23 + */
   20.24 +
   20.25 +/*
   20.26 + * This file handles the architecture-dependent parts of initialization
   20.27 + */
   20.28 +
   20.29 +#include <linux/sched.h>
   20.30 +#include <linux/mm.h>
   20.31 +#include <linux/tty.h>
   20.32 +#include <linux/ioport.h>
   20.33 +#include <linux/acpi.h>
   20.34 +#include <linux/apm_bios.h>
   20.35 +#include <linux/initrd.h>
   20.36 +#include <linux/bootmem.h>
   20.37 +#include <linux/seq_file.h>
   20.38 +#include <linux/console.h>
   20.39 +#include <linux/root_dev.h>
   20.40 +#include <linux/highmem.h>
   20.41 +#include <linux/module.h>
   20.42 +#include <linux/efi.h>
   20.43 +#include <linux/init.h>
   20.44 +#include <linux/edd.h>
   20.45 +#include <video/edid.h>
   20.46 +#include <asm/e820.h>
   20.47 +#include <asm/mpspec.h>
   20.48 +#include <asm/setup.h>
   20.49 +#include <asm/arch_hooks.h>
   20.50 +#include <asm/sections.h>
   20.51 +#include <asm/io_apic.h>
   20.52 +#include <asm/ist.h>
   20.53 +#include <asm/std_resources.h>
   20.54 +#include <asm/hypervisor.h>
   20.55 +#include "setup_arch_pre.h"
   20.56 +
   20.57 +int disable_pse __initdata = 0;
   20.58 +
   20.59 +static inline char * __init machine_specific_memory_setup(void);
   20.60 +
   20.61 +/*
   20.62 + * Machine setup..
   20.63 + */
   20.64 +
   20.65 +#ifdef CONFIG_EFI
   20.66 +int efi_enabled = 0;
   20.67 +EXPORT_SYMBOL(efi_enabled);
   20.68 +#endif
   20.69 +
   20.70 +/* cpu data as detected by the assembly code in head.S */
   20.71 +struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 0, 1, 0, -1 };
   20.72 +/* common cpu data for all cpus */
   20.73 +struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 0, 1, 0, -1 };
   20.74 +
   20.75 +unsigned long mmu_cr4_features;
   20.76 +EXPORT_SYMBOL_GPL(mmu_cr4_features);
   20.77 +
   20.78 +#ifdef	CONFIG_ACPI_INTERPRETER
   20.79 +	int acpi_disabled = 0;
   20.80 +#else
   20.81 +	int acpi_disabled = 1;
   20.82 +#endif
   20.83 +EXPORT_SYMBOL(acpi_disabled);
   20.84 +
   20.85 +#ifdef	CONFIG_ACPI_BOOT
   20.86 +int __initdata acpi_force = 0;
   20.87 +extern acpi_interrupt_flags	acpi_sci_flags;
   20.88 +#endif
   20.89 +
   20.90 +int MCA_bus;
   20.91 +/* for MCA, but anyone else can use it if they want */
   20.92 +unsigned int machine_id;
   20.93 +unsigned int machine_submodel_id;
   20.94 +unsigned int BIOS_revision;
   20.95 +unsigned int mca_pentium_flag;
   20.96 +
   20.97 +/* For PCI or other memory-mapped resources */
   20.98 +unsigned long pci_mem_start = 0x10000000;
   20.99 +
  20.100 +/* user-defined highmem size */
  20.101 +static unsigned int highmem_pages = -1;
  20.102 +
  20.103 +/*
  20.104 + * Setup options
  20.105 + */
  20.106 +struct drive_info_struct { char dummy[32]; } drive_info;
  20.107 +struct screen_info screen_info;
  20.108 +struct apm_info apm_info;
  20.109 +struct sys_desc_table_struct {
  20.110 +	unsigned short length;
  20.111 +	unsigned char table[0];
  20.112 +};
  20.113 +struct edid_info edid_info;
  20.114 +struct ist_info ist_info;
  20.115 +struct e820map e820;
  20.116 +
  20.117 +unsigned char aux_device_present;
  20.118 +
  20.119 +extern void early_cpu_init(void);
  20.120 +extern void dmi_scan_machine(void);
  20.121 +extern void generic_apic_probe(char *);
  20.122 +extern int root_mountflags;
  20.123 +
  20.124 +unsigned long saved_videomode;
  20.125 +
  20.126 +#define RAMDISK_IMAGE_START_MASK  	0x07FF
  20.127 +#define RAMDISK_PROMPT_FLAG		0x8000
  20.128 +#define RAMDISK_LOAD_FLAG		0x4000	
  20.129 +
  20.130 +static char command_line[COMMAND_LINE_SIZE];
  20.131 +       char saved_command_line[COMMAND_LINE_SIZE];
  20.132 +
  20.133 +unsigned char __initdata boot_params[PARAM_SIZE];
  20.134 +
  20.135 +static struct resource code_resource = { "Kernel code", 0x100000, 0 };
  20.136 +static struct resource data_resource = { "Kernel data", 0, 0 };
  20.137 +
  20.138 +/*
  20.139 + * Point at the empty zero page to start with. We map the real shared_info
  20.140 + * page as soon as fixmap is up and running.
  20.141 + */
  20.142 +shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
  20.143 +
  20.144 +unsigned long *phys_to_machine_mapping;
  20.145 +
  20.146 +multicall_entry_t multicall_list[8];
  20.147 +int nr_multicall_ents = 0;
  20.148 +
  20.149 +/* Raw start-of-day parameters from the hypervisor. */
  20.150 +union start_info_union start_info_union;
  20.151 +
  20.152 +static void __init limit_regions(unsigned long long size)
  20.153 +{
  20.154 +	unsigned long long current_addr = 0;
  20.155 +	int i;
  20.156 +
  20.157 +	if (efi_enabled) {
  20.158 +		for (i = 0; i < memmap.nr_map; i++) {
  20.159 +			current_addr = memmap.map[i].phys_addr +
  20.160 +				       (memmap.map[i].num_pages << 12);
  20.161 +			if (memmap.map[i].type == EFI_CONVENTIONAL_MEMORY) {
  20.162 +				if (current_addr >= size) {
  20.163 +					memmap.map[i].num_pages -=
  20.164 +						(((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
  20.165 +					memmap.nr_map = i + 1;
  20.166 +					return;
  20.167 +				}
  20.168 +			}
  20.169 +		}
  20.170 +	}
  20.171 +	for (i = 0; i < e820.nr_map; i++) {
  20.172 +		if (e820.map[i].type == E820_RAM) {
  20.173 +			current_addr = e820.map[i].addr + e820.map[i].size;
  20.174 +			if (current_addr >= size) {
  20.175 +				e820.map[i].size -= current_addr-size;
  20.176 +				e820.nr_map = i + 1;
  20.177 +				return;
  20.178 +			}
  20.179 +		}
  20.180 +	}
  20.181 +}
  20.182 +
  20.183 +static void __init add_memory_region(unsigned long long start,
  20.184 +                                  unsigned long long size, int type)
  20.185 +{
  20.186 +	int x;
  20.187 +
  20.188 +	if (!efi_enabled) {
  20.189 +       		x = e820.nr_map;
  20.190 +
  20.191 +		if (x == E820MAX) {
  20.192 +		    printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
  20.193 +		    return;
  20.194 +		}
  20.195 +
  20.196 +		e820.map[x].addr = start;
  20.197 +		e820.map[x].size = size;
  20.198 +		e820.map[x].type = type;
  20.199 +		e820.nr_map++;
  20.200 +	}
  20.201 +} /* add_memory_region */
  20.202 +
  20.203 +#define E820_DEBUG	1
  20.204 +
  20.205 +static void __init print_memory_map(char *who)
  20.206 +{
  20.207 +	int i;
  20.208 +
  20.209 +	for (i = 0; i < e820.nr_map; i++) {
  20.210 +		printk(" %s: %016Lx - %016Lx ", who,
  20.211 +			e820.map[i].addr,
  20.212 +			e820.map[i].addr + e820.map[i].size);
  20.213 +		switch (e820.map[i].type) {
  20.214 +		case E820_RAM:	printk("(usable)\n");
  20.215 +				break;
  20.216 +		case E820_RESERVED:
  20.217 +				printk("(reserved)\n");
  20.218 +				break;
  20.219 +		case E820_ACPI:
  20.220 +				printk("(ACPI data)\n");
  20.221 +				break;
  20.222 +		case E820_NVS:
  20.223 +				printk("(ACPI NVS)\n");
  20.224 +				break;
  20.225 +		default:	printk("type %lu\n", e820.map[i].type);
  20.226 +				break;
  20.227 +		}
  20.228 +	}
  20.229 +}
  20.230 +
  20.231 +#if 0
  20.232 +/*
  20.233 + * Sanitize the BIOS e820 map.
  20.234 + *
  20.235 + * Some e820 responses include overlapping entries.  The following 
  20.236 + * replaces the original e820 map with a new one, removing overlaps.
  20.237 + *
  20.238 + */
  20.239 +struct change_member {
  20.240 +	struct e820entry *pbios; /* pointer to original bios entry */
  20.241 +	unsigned long long addr; /* address for this change point */
  20.242 +};
  20.243 +struct change_member change_point_list[2*E820MAX] __initdata;
  20.244 +struct change_member *change_point[2*E820MAX] __initdata;
  20.245 +struct e820entry *overlap_list[E820MAX] __initdata;
  20.246 +struct e820entry new_bios[E820MAX] __initdata;
  20.247 +
  20.248 +static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
  20.249 +{
  20.250 +	struct change_member *change_tmp;
  20.251 +	unsigned long current_type, last_type;
  20.252 +	unsigned long long last_addr;
  20.253 +	int chgidx, still_changing;
  20.254 +	int overlap_entries;
  20.255 +	int new_bios_entry;
  20.256 +	int old_nr, new_nr, chg_nr;
  20.257 +	int i;
  20.258 +
  20.259 +	/*
  20.260 +		Visually we're performing the following (1,2,3,4 = memory types)...
  20.261 +
  20.262 +		Sample memory map (w/overlaps):
  20.263 +		   ____22__________________
  20.264 +		   ______________________4_
  20.265 +		   ____1111________________
  20.266 +		   _44_____________________
  20.267 +		   11111111________________
  20.268 +		   ____________________33__
  20.269 +		   ___________44___________
  20.270 +		   __________33333_________
  20.271 +		   ______________22________
  20.272 +		   ___________________2222_
  20.273 +		   _________111111111______
  20.274 +		   _____________________11_
  20.275 +		   _________________4______
  20.276 +
  20.277 +		Sanitized equivalent (no overlap):
  20.278 +		   1_______________________
  20.279 +		   _44_____________________
  20.280 +		   ___1____________________
  20.281 +		   ____22__________________
  20.282 +		   ______11________________
  20.283 +		   _________1______________
  20.284 +		   __________3_____________
  20.285 +		   ___________44___________
  20.286 +		   _____________33_________
  20.287 +		   _______________2________
  20.288 +		   ________________1_______
  20.289 +		   _________________4______
  20.290 +		   ___________________2____
  20.291 +		   ____________________33__
  20.292 +		   ______________________4_
  20.293 +	*/
  20.294 +
  20.295 +	/* if there's only one memory region, don't bother */
  20.296 +	if (*pnr_map < 2)
  20.297 +		return -1;
  20.298 +
  20.299 +	old_nr = *pnr_map;
  20.300 +
  20.301 +	/* bail out if we find any unreasonable addresses in bios map */
  20.302 +	for (i=0; i<old_nr; i++)
  20.303 +		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
  20.304 +			return -1;
  20.305 +
  20.306 +	/* create pointers for initial change-point information (for sorting) */
  20.307 +	for (i=0; i < 2*old_nr; i++)
  20.308 +		change_point[i] = &change_point_list[i];
  20.309 +
  20.310 +	/* record all known change-points (starting and ending addresses),
  20.311 +	   omitting those that are for empty memory regions */
  20.312 +	chgidx = 0;
  20.313 +	for (i=0; i < old_nr; i++)	{
  20.314 +		if (biosmap[i].size != 0) {
  20.315 +			change_point[chgidx]->addr = biosmap[i].addr;
  20.316 +			change_point[chgidx++]->pbios = &biosmap[i];
  20.317 +			change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
  20.318 +			change_point[chgidx++]->pbios = &biosmap[i];
  20.319 +		}
  20.320 +	}
  20.321 +	chg_nr = chgidx;    	/* true number of change-points */
  20.322 +
  20.323 +	/* sort change-point list by memory addresses (low -> high) */
  20.324 +	still_changing = 1;
  20.325 +	while (still_changing)	{
  20.326 +		still_changing = 0;
  20.327 +		for (i=1; i < chg_nr; i++)  {
  20.328 +			/* if <current_addr> > <last_addr>, swap */
  20.329 +			/* or, if current=<start_addr> & last=<end_addr>, swap */
  20.330 +			if ((change_point[i]->addr < change_point[i-1]->addr) ||
  20.331 +				((change_point[i]->addr == change_point[i-1]->addr) &&
  20.332 +				 (change_point[i]->addr == change_point[i]->pbios->addr) &&
  20.333 +				 (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
  20.334 +			   )
  20.335 +			{
  20.336 +				change_tmp = change_point[i];
  20.337 +				change_point[i] = change_point[i-1];
  20.338 +				change_point[i-1] = change_tmp;
  20.339 +				still_changing=1;
  20.340 +			}
  20.341 +		}
  20.342 +	}
  20.343 +
  20.344 +	/* create a new bios memory map, removing overlaps */
  20.345 +	overlap_entries=0;	 /* number of entries in the overlap table */
  20.346 +	new_bios_entry=0;	 /* index for creating new bios map entries */
  20.347 +	last_type = 0;		 /* start with undefined memory type */
  20.348 +	last_addr = 0;		 /* start with 0 as last starting address */
  20.349 +	/* loop through change-points, determining affect on the new bios map */
  20.350 +	for (chgidx=0; chgidx < chg_nr; chgidx++)
  20.351 +	{
  20.352 +		/* keep track of all overlapping bios entries */
  20.353 +		if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
  20.354 +		{
  20.355 +			/* add map entry to overlap list (> 1 entry implies an overlap) */
  20.356 +			overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
  20.357 +		}
  20.358 +		else
  20.359 +		{
  20.360 +			/* remove entry from list (order independent, so swap with last) */
  20.361 +			for (i=0; i<overlap_entries; i++)
  20.362 +			{
  20.363 +				if (overlap_list[i] == change_point[chgidx]->pbios)
  20.364 +					overlap_list[i] = overlap_list[overlap_entries-1];
  20.365 +			}
  20.366 +			overlap_entries--;
  20.367 +		}
  20.368 +		/* if there are overlapping entries, decide which "type" to use */
  20.369 +		/* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
  20.370 +		current_type = 0;
  20.371 +		for (i=0; i<overlap_entries; i++)
  20.372 +			if (overlap_list[i]->type > current_type)
  20.373 +				current_type = overlap_list[i]->type;
  20.374 +		/* continue building up new bios map based on this information */
  20.375 +		if (current_type != last_type)	{
  20.376 +			if (last_type != 0)	 {
  20.377 +				new_bios[new_bios_entry].size =
  20.378 +					change_point[chgidx]->addr - last_addr;
  20.379 +				/* move forward only if the new size was non-zero */
  20.380 +				if (new_bios[new_bios_entry].size != 0)
  20.381 +					if (++new_bios_entry >= E820MAX)
  20.382 +						break; 	/* no more space left for new bios entries */
  20.383 +			}
  20.384 +			if (current_type != 0)	{
  20.385 +				new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
  20.386 +				new_bios[new_bios_entry].type = current_type;
  20.387 +				last_addr=change_point[chgidx]->addr;
  20.388 +			}
  20.389 +			last_type = current_type;
  20.390 +		}
  20.391 +	}
  20.392 +	new_nr = new_bios_entry;   /* retain count for new bios entries */
  20.393 +
  20.394 +	/* copy new bios mapping into original location */
  20.395 +	memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
  20.396 +	*pnr_map = new_nr;
  20.397 +
  20.398 +	return 0;
  20.399 +}
  20.400 +
  20.401 +/*
  20.402 + * Copy the BIOS e820 map into a safe place.
  20.403 + *
  20.404 + * Sanity-check it while we're at it..
  20.405 + *
  20.406 + * If we're lucky and live on a modern system, the setup code
  20.407 + * will have given us a memory map that we can use to properly
  20.408 + * set up memory.  If we aren't, we'll fake a memory map.
  20.409 + *
  20.410 + * We check to see that the memory map contains at least 2 elements
  20.411 + * before we'll use it, because the detection code in setup.S may
  20.412 + * not be perfect and most every PC known to man has two memory
  20.413 + * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
  20.414 + * thinkpad 560x, for example, does not cooperate with the memory
  20.415 + * detection code.)
  20.416 + */
  20.417 +static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
  20.418 +{
  20.419 +	/* Only one memory region (or negative)? Ignore it */
  20.420 +	if (nr_map < 2)
  20.421 +		return -1;
  20.422 +
  20.423 +	do {
  20.424 +		unsigned long long start = biosmap->addr;
  20.425 +		unsigned long long size = biosmap->size;
  20.426 +		unsigned long long end = start + size;
  20.427 +		unsigned long type = biosmap->type;
  20.428 +
  20.429 +		/* Overflow in 64 bits? Ignore the memory map. */
  20.430 +		if (start > end)
  20.431 +			return -1;
  20.432 +
  20.433 +		/*
  20.434 +		 * Some BIOSes claim RAM in the 640k - 1M region.
  20.435 +		 * Not right. Fix it up.
  20.436 +		 */
  20.437 +		if (type == E820_RAM) {
  20.438 +			if (start < 0x100000ULL && end > 0xA0000ULL) {
  20.439 +				if (start < 0xA0000ULL)
  20.440 +					add_memory_region(start, 0xA0000ULL-start, type);
  20.441 +				if (end <= 0x100000ULL)
  20.442 +					continue;
  20.443 +				start = 0x100000ULL;
  20.444 +				size = end - start;
  20.445 +			}
  20.446 +		}
  20.447 +		add_memory_region(start, size, type);
  20.448 +	} while (biosmap++,--nr_map);
  20.449 +	return 0;
  20.450 +}
  20.451 +#endif
  20.452 +
  20.453 +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
  20.454 +unsigned char eddnr;
  20.455 +struct edd_info edd[EDDMAXNR];
  20.456 +unsigned int edd_disk80_sig;
  20.457 +#ifdef CONFIG_EDD_MODULE
  20.458 +EXPORT_SYMBOL(eddnr);
  20.459 +EXPORT_SYMBOL(edd);
  20.460 +EXPORT_SYMBOL(edd_disk80_sig);
  20.461 +#endif
  20.462 +/**
  20.463 + * copy_edd() - Copy the BIOS EDD information
  20.464 + *              from boot_params into a safe place.
  20.465 + *
  20.466 + */
  20.467 +static inline void copy_edd(void)
  20.468 +{
  20.469 +     eddnr = EDD_NR;
  20.470 +     memcpy(edd, EDD_BUF, sizeof(edd));
  20.471 +     edd_disk80_sig = DISK80_SIGNATURE;
  20.472 +}
  20.473 +#else
  20.474 +#define copy_edd() do {} while (0)
  20.475 +#endif
  20.476 +
  20.477 +/*
  20.478 + * Do NOT EVER look at the BIOS memory size location.
  20.479 + * It does not work on many machines.
  20.480 + */
  20.481 +#define LOWMEMSIZE()	(0x9f000)
  20.482 +
  20.483 +static void __init setup_memory_region(void)
  20.484 +{
  20.485 +	char *who = machine_specific_memory_setup();
  20.486 +	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
  20.487 +	print_memory_map(who);
  20.488 +} /* setup_memory_region */
  20.489 +
  20.490 +
  20.491 +static void __init parse_cmdline_early (char ** cmdline_p)
  20.492 +{
  20.493 +	char c = ' ', *to = command_line, *from = saved_command_line;
  20.494 +	int len = 0;
  20.495 +	int userdef = 0;
  20.496 +
  20.497 +        memcpy(saved_command_line, start_info.cmd_line, MAX_CMDLINE);
  20.498 +	/* Save unparsed command line copy for /proc/cmdline */
  20.499 +	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
  20.500 +
  20.501 +	for (;;) {
  20.502 +		/*
  20.503 +		 * "mem=nopentium" disables the 4MB page tables.
  20.504 +		 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
  20.505 +		 * to <mem>, overriding the bios size.
  20.506 +		 * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from
  20.507 +		 * <start> to <start>+<mem>, overriding the bios size.
  20.508 +		 *
  20.509 +		 * HPA tells me bootloaders need to parse mem=, so no new
  20.510 +		 * option should be mem=  [also see Documentation/i386/boot.txt]
  20.511 +		 */
  20.512 +		if (c == ' ' && !memcmp(from, "mem=", 4)) {
  20.513 +			if (to != command_line)
  20.514 +				to--;
  20.515 +			if (!memcmp(from+4, "nopentium", 9)) {
  20.516 +				from += 9+4;
  20.517 +				clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
  20.518 +				disable_pse = 1;
  20.519 +			} else {
  20.520 +				/* If the user specifies memory size, we
  20.521 +				 * limit the BIOS-provided memory map to
  20.522 +				 * that size. exactmap can be used to specify
  20.523 +				 * the exact map. mem=number can be used to
  20.524 +				 * trim the existing memory map.
  20.525 +				 */
  20.526 +				unsigned long long mem_size;
  20.527 + 
  20.528 +				mem_size = memparse(from+4, &from);
  20.529 +				limit_regions(mem_size);
  20.530 +				userdef=1;
  20.531 +			}
  20.532 +		}
  20.533 +
  20.534 +		if (c == ' ' && !memcmp(from, "memmap=", 7)) {
  20.535 +			if (to != command_line)
  20.536 +				to--;
  20.537 +			if (!memcmp(from+7, "exactmap", 8)) {
  20.538 +				from += 8+7;
  20.539 +				e820.nr_map = 0;
  20.540 +				userdef = 1;
  20.541 +			} else {
  20.542 +				/* If the user specifies memory size, we
  20.543 +				 * limit the BIOS-provided memory map to
  20.544 +				 * that size. exactmap can be used to specify
  20.545 +				 * the exact map. mem=number can be used to
  20.546 +				 * trim the existing memory map.
  20.547 +				 */
  20.548 +				unsigned long long start_at, mem_size;
  20.549 + 
  20.550 +				mem_size = memparse(from+7, &from);
  20.551 +				if (*from == '@') {
  20.552 +					start_at = memparse(from+1, &from);
  20.553 +					add_memory_region(start_at, mem_size, E820_RAM);
  20.554 +				} else if (*from == '#') {
  20.555 +					start_at = memparse(from+1, &from);
  20.556 +					add_memory_region(start_at, mem_size, E820_ACPI);
  20.557 +				} else if (*from == '$') {
  20.558 +					start_at = memparse(from+1, &from);
  20.559 +					add_memory_region(start_at, mem_size, E820_RESERVED);
  20.560 +				} else {
  20.561 +					limit_regions(mem_size);
  20.562 +					userdef=1;
  20.563 +				}
  20.564 +			}
  20.565 +		}
  20.566 +
  20.567 +#ifdef  CONFIG_X86_SMP
  20.568 +		/*
  20.569 +		 * If the BIOS enumerates physical processors before logical,
  20.570 +		 * maxcpus=N at enumeration-time can be used to disable HT.
  20.571 +		 */
  20.572 +		else if (!memcmp(from, "maxcpus=", 8)) {
  20.573 +			extern unsigned int maxcpus;
  20.574 +
  20.575 +			maxcpus = simple_strtoul(from + 8, NULL, 0);
  20.576 +		}
  20.577 +#endif
  20.578 +
  20.579 +#ifdef CONFIG_ACPI_BOOT
  20.580 +		/* "acpi=off" disables both ACPI table parsing and interpreter */
  20.581 +		else if (!memcmp(from, "acpi=off", 8)) {
  20.582 +			disable_acpi();
  20.583 +		}
  20.584 +
  20.585 +		/* acpi=force to over-ride black-list */
  20.586 +		else if (!memcmp(from, "acpi=force", 10)) {
  20.587 +			acpi_force = 1;
  20.588 +			acpi_ht = 1;
  20.589 +			acpi_disabled = 0;
  20.590 +		}
  20.591 +
  20.592 +		/* acpi=strict disables out-of-spec workarounds */
  20.593 +		else if (!memcmp(from, "acpi=strict", 11)) {
  20.594 +			acpi_strict = 1;
  20.595 +		}
  20.596 +
  20.597 +		/* Limit ACPI just to boot-time to enable HT */
  20.598 +		else if (!memcmp(from, "acpi=ht", 7)) {
  20.599 +			if (!acpi_force)
  20.600 +				disable_acpi();
  20.601 +			acpi_ht = 1;
  20.602 +		}
  20.603 +		
  20.604 +		/* "pci=noacpi" disable ACPI IRQ routing and PCI scan */
  20.605 +		else if (!memcmp(from, "pci=noacpi", 10)) {
  20.606 +			acpi_disable_pci();
  20.607 +		}
  20.608 +		/* "acpi=noirq" disables ACPI interrupt routing */
  20.609 +		else if (!memcmp(from, "acpi=noirq", 10)) {
  20.610 +			acpi_noirq_set();
  20.611 +		}
  20.612 +
  20.613 +		else if (!memcmp(from, "acpi_sci=edge", 13))
  20.614 +			acpi_sci_flags.trigger =  1;
  20.615 +
  20.616 +		else if (!memcmp(from, "acpi_sci=level", 14))
  20.617 +			acpi_sci_flags.trigger = 3;
  20.618 +
  20.619 +		else if (!memcmp(from, "acpi_sci=high", 13))
  20.620 +			acpi_sci_flags.polarity = 1;
  20.621 +
  20.622 +		else if (!memcmp(from, "acpi_sci=low", 12))
  20.623 +			acpi_sci_flags.polarity = 3;
  20.624 +
  20.625 +#ifdef CONFIG_X86_IO_APIC
  20.626 +		else if (!memcmp(from, "acpi_skip_timer_override", 24))
  20.627 +			acpi_skip_timer_override = 1;
  20.628 +#endif
  20.629 +
  20.630 +#ifdef CONFIG_X86_LOCAL_APIC
  20.631 +		/* disable IO-APIC */
  20.632 +		else if (!memcmp(from, "noapic", 6))
  20.633 +			disable_ioapic_setup();
  20.634 +#endif /* CONFIG_X86_LOCAL_APIC */
  20.635 +#endif /* CONFIG_ACPI_BOOT */
  20.636 +
  20.637 +		/*
  20.638 +		 * highmem=size forces highmem to be exactly 'size' bytes.
  20.639 +		 * This works even on boxes that have no highmem otherwise.
  20.640 +		 * This also works to reduce highmem size on bigger boxes.
  20.641 +		 */
  20.642 +		if (c == ' ' && !memcmp(from, "highmem=", 8))
  20.643 +			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
  20.644 +	
  20.645 +		c = *(from++);
  20.646 +		if (!c)
  20.647 +			break;
  20.648 +		if (COMMAND_LINE_SIZE <= ++len)
  20.649 +			break;
  20.650 +		*(to++) = c;
  20.651 +	}
  20.652 +	*to = '\0';
  20.653 +	*cmdline_p = command_line;
  20.654 +	if (userdef) {
  20.655 +		printk(KERN_INFO "user-defined physical RAM map:\n");
  20.656 +		print_memory_map("user");
  20.657 +	}
  20.658 +}
  20.659 +
  20.660 +/*
  20.661 + * Callback for efi_memory_walk.
  20.662 + */
  20.663 +static int __init
  20.664 +efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
  20.665 +{
  20.666 +	unsigned long *max_pfn = arg, pfn;
  20.667 +
  20.668 +	if (start < end) {
  20.669 +		pfn = PFN_UP(end -1);
  20.670 +		if (pfn > *max_pfn)
  20.671 +			*max_pfn = pfn;
  20.672 +	}
  20.673 +	return 0;
  20.674 +}
  20.675 +
  20.676 +
  20.677 +/*
  20.678 + * Find the highest page frame number we have available
  20.679 + */
  20.680 +void __init find_max_pfn(void)
  20.681 +{
  20.682 +	int i;
  20.683 +
  20.684 +	max_pfn = 0;
  20.685 +	if (efi_enabled) {
  20.686 +		efi_memmap_walk(efi_find_max_pfn, &max_pfn);
  20.687 +		return;
  20.688 +	}
  20.689 +
  20.690 +	for (i = 0; i < e820.nr_map; i++) {
  20.691 +		unsigned long start, end;
  20.692 +		/* RAM? */
  20.693 +		if (e820.map[i].type != E820_RAM)
  20.694 +			continue;
  20.695 +		start = PFN_UP(e820.map[i].addr);
  20.696 +		end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
  20.697 +		if (start >= end)
  20.698 +			continue;
  20.699 +		if (end > max_pfn)
  20.700 +			max_pfn = end;
  20.701 +	}
  20.702 +}
  20.703 +
  20.704 +/*
  20.705 + * Determine low and high memory ranges:
  20.706 + */
  20.707 +unsigned long __init find_max_low_pfn(void)
  20.708 +{
  20.709 +	unsigned long max_low_pfn;
  20.710 +
  20.711 +	max_low_pfn = max_pfn;
  20.712 +	if (max_low_pfn > MAXMEM_PFN) {
  20.713 +		if (highmem_pages == -1)
  20.714 +			highmem_pages = max_pfn - MAXMEM_PFN;
  20.715 +		if (highmem_pages + MAXMEM_PFN < max_pfn)
  20.716 +			max_pfn = MAXMEM_PFN + highmem_pages;
  20.717 +		if (highmem_pages + MAXMEM_PFN > max_pfn) {
  20.718 +			printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages));
  20.719 +			highmem_pages = 0;
  20.720 +		}
  20.721 +		max_low_pfn = MAXMEM_PFN;
  20.722 +#ifndef CONFIG_HIGHMEM
  20.723 +		/* Maximum memory usable is what is directly addressable */
  20.724 +		printk(KERN_WARNING "Warning only %ldMB will be used.\n",
  20.725 +					MAXMEM>>20);
  20.726 +		if (max_pfn > MAX_NONPAE_PFN)
  20.727 +			printk(KERN_WARNING "Use a PAE enabled kernel.\n");
  20.728 +		else
  20.729 +			printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
  20.730 +		max_pfn = MAXMEM_PFN;
  20.731 +#else /* !CONFIG_HIGHMEM */
  20.732 +#ifndef CONFIG_X86_PAE
  20.733 +		if (max_pfn > MAX_NONPAE_PFN) {
  20.734 +			max_pfn = MAX_NONPAE_PFN;
  20.735 +			printk(KERN_WARNING "Warning only 4GB will be used.\n");
  20.736 +			printk(KERN_WARNING "Use a PAE enabled kernel.\n");
  20.737 +		}
  20.738 +#endif /* !CONFIG_X86_PAE */
  20.739 +#endif /* !CONFIG_HIGHMEM */
  20.740 +	} else {
  20.741 +		if (highmem_pages == -1)
  20.742 +			highmem_pages = 0;
  20.743 +#ifdef CONFIG_HIGHMEM
  20.744 +		if (highmem_pages >= max_pfn) {
  20.745 +			printk(KERN_ERR "highmem size specified (%uMB) is bigger than pages available (%luMB)!.\n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
  20.746 +			highmem_pages = 0;
  20.747 +		}
  20.748 +		if (highmem_pages) {
  20.749 +			if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
  20.750 +				printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages));
  20.751 +				highmem_pages = 0;
  20.752 +			}
  20.753 +			max_low_pfn -= highmem_pages;
  20.754 +		}
  20.755 +#else
  20.756 +		if (highmem_pages)
  20.757 +			printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
  20.758 +#endif
  20.759 +	}
  20.760 +	return max_low_pfn;
  20.761 +}
  20.762 +
  20.763 +#ifndef CONFIG_DISCONTIGMEM
  20.764 +
  20.765 +/*
  20.766 + * Free all available memory for boot time allocation.  Used
  20.767 + * as a callback function by efi_memory_walk()
  20.768 + */
  20.769 +
  20.770 +static int __init
  20.771 +free_available_memory(unsigned long start, unsigned long end, void *arg)
  20.772 +{
  20.773 +	/* check max_low_pfn */
  20.774 +	if (start >= ((max_low_pfn + 1) << PAGE_SHIFT))
  20.775 +		return 0;
  20.776 +	if (end >= ((max_low_pfn + 1) << PAGE_SHIFT))
  20.777 +		end = (max_low_pfn + 1) << PAGE_SHIFT;
  20.778 +	if (start < end)
  20.779 +		free_bootmem(start, end - start);
  20.780 +
  20.781 +	return 0;
  20.782 +}
  20.783 +/*
  20.784 + * Register fully available low RAM pages with the bootmem allocator.
  20.785 + */
  20.786 +static void __init register_bootmem_low_pages(unsigned long max_low_pfn)
  20.787 +{
  20.788 +	int i;
  20.789 +
  20.790 +	if (efi_enabled) {
  20.791 +		efi_memmap_walk(free_available_memory, NULL);
  20.792 +		return;
  20.793 +	}
  20.794 +	for (i = 0; i < e820.nr_map; i++) {
  20.795 +		unsigned long curr_pfn, last_pfn, size;
  20.796 +		/*
  20.797 +		 * Reserve usable low memory
  20.798 +		 */
  20.799 +		if (e820.map[i].type != E820_RAM)
  20.800 +			continue;
  20.801 +		/*
  20.802 +		 * We are rounding up the start address of usable memory:
  20.803 +		 */
  20.804 +		curr_pfn = PFN_UP(e820.map[i].addr);
  20.805 +		if (curr_pfn >= max_low_pfn)
  20.806 +			continue;
  20.807 +		/*
  20.808 +		 * ... and at the end of the usable range downwards:
  20.809 +		 */
  20.810 +		last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
  20.811 +
  20.812 +		if (last_pfn > max_low_pfn)
  20.813 +			last_pfn = max_low_pfn;
  20.814 +
  20.815 +		/*
  20.816 +		 * .. finally, did all the rounding and playing
  20.817 +		 * around just make the area go away?
  20.818 +		 */
  20.819 +		if (last_pfn <= curr_pfn)
  20.820 +			continue;
  20.821 +
  20.822 +		size = last_pfn - curr_pfn;
  20.823 +		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
  20.824 +	}
  20.825 +}
  20.826 +
  20.827 +static unsigned long __init setup_memory(void)
  20.828 +{
  20.829 +	unsigned long bootmap_size, start_pfn, max_low_pfn;
  20.830 +
  20.831 +	/*
  20.832 +	 * partially used pages are not usable - thus
  20.833 +	 * we are rounding upwards:
  20.834 +	 */
  20.835 +	start_pfn = PFN_UP(__pa(start_info.pt_base)) + start_info.nr_pt_frames;
  20.836 +
  20.837 +	find_max_pfn();
  20.838 +
  20.839 +	max_low_pfn = find_max_low_pfn();
  20.840 +
  20.841 +#ifdef CONFIG_HIGHMEM
  20.842 +	highstart_pfn = highend_pfn = max_pfn;
  20.843 +	if (max_pfn > max_low_pfn) {
  20.844 +		highstart_pfn = max_low_pfn;
  20.845 +	}
  20.846 +	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
  20.847 +		pages_to_mb(highend_pfn - highstart_pfn));
  20.848 +#endif
  20.849 +	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
  20.850 +			pages_to_mb(max_low_pfn));
  20.851 +	/*
  20.852 +	 * Initialize the boot-time allocator (with low memory only):
  20.853 +	 */
  20.854 +	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
  20.855 +
  20.856 +	register_bootmem_low_pages(max_low_pfn);
  20.857 +
  20.858 +	/*
  20.859 +	 * Reserve the bootmem bitmap itself as well. We do this in two
  20.860 +	 * steps (first step was init_bootmem()) because this catches
  20.861 +	 * the (very unlikely) case of us accidentally initializing the
  20.862 +	 * bootmem allocator with an invalid RAM area.
  20.863 +	 */
  20.864 +	reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
  20.865 +			 bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
  20.866 +
  20.867 +    /* could be an AMD 768MPX chipset. Reserve a page  before VGA to prevent
  20.868 +       PCI prefetch into it (errata #56). Usually the page is reserved anyways,
  20.869 +       unless you have no PS/2 mouse plugged in. */
  20.870 +	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
  20.871 +	    boot_cpu_data.x86 == 6)
  20.872 +	     reserve_bootmem(0xa0000 - 4096, 4096);
  20.873 +
  20.874 +#ifdef CONFIG_SMP
  20.875 +	/*
  20.876 +	 * But first pinch a few for the stack/trampoline stuff
  20.877 +	 * FIXME: Don't need the extra page at 4K, but need to fix
  20.878 +	 * trampoline before removing it. (see the GDT stuff)
  20.879 +	 */
  20.880 +	reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
  20.881 +#endif
  20.882 +#ifdef CONFIG_ACPI_SLEEP
  20.883 +	/*
  20.884 +	 * Reserve low memory region for sleep support.
  20.885 +	 */
  20.886 +	acpi_reserve_bootmem();
  20.887 +#endif
  20.888 +#ifdef CONFIG_X86_FIND_SMP_CONFIG
  20.889 +	/*
  20.890 +	 * Find and reserve possible boot-time SMP configuration:
  20.891 +	 */
  20.892 +	find_smp_config();
  20.893 +#endif
  20.894 +
  20.895 +#ifdef CONFIG_BLK_DEV_INITRD
  20.896 +	if (LOADER_TYPE && INITRD_START) {
  20.897 +		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
  20.898 +			reserve_bootmem(INITRD_START, INITRD_SIZE);
  20.899 +			initrd_start =
  20.900 +				INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
  20.901 +			initrd_end = initrd_start+INITRD_SIZE;
  20.902 +		}
  20.903 +		else {
  20.904 +			printk(KERN_ERR "initrd extends beyond end of memory "
  20.905 +			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
  20.906 +			    INITRD_START + INITRD_SIZE,
  20.907 +			    max_low_pfn << PAGE_SHIFT);
  20.908 +			initrd_start = 0;
  20.909 +		}
  20.910 +	}
  20.911 +#endif
  20.912 +
  20.913 +	phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
  20.914 +
  20.915 +	return max_low_pfn;
  20.916 +}
  20.917 +#else
  20.918 +extern unsigned long setup_memory(void);
  20.919 +#endif /* !CONFIG_DISCONTIGMEM */
  20.920 +
  20.921 +/*
  20.922 + * Request address space for all standard RAM and ROM resources
  20.923 + * and also for regions reported as reserved by the e820.
  20.924 + */
  20.925 +static void __init
  20.926 +legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
  20.927 +{
  20.928 +	int i;
  20.929 +
  20.930 +#ifdef CONFIG_XEN_PHYSDEV_ACCESS
  20.931 +	probe_roms();
  20.932 +#endif
  20.933 +	for (i = 0; i < e820.nr_map; i++) {
  20.934 +		struct resource *res;
  20.935 +		if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
  20.936 +			continue;
  20.937 +		res = alloc_bootmem_low(sizeof(struct resource));
  20.938 +		switch (e820.map[i].type) {
  20.939 +		case E820_RAM:	res->name = "System RAM"; break;
  20.940 +		case E820_ACPI:	res->name = "ACPI Tables"; break;
  20.941 +		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;
  20.942 +		default:	res->name = "reserved";
  20.943 +		}
  20.944 +		res->start = e820.map[i].addr;
  20.945 +		res->end = res->start + e820.map[i].size - 1;
  20.946 +		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  20.947 +		request_resource(&iomem_resource, res);
  20.948 +		if (e820.map[i].type == E820_RAM) {
  20.949 +			/*
  20.950 +			 *  We don't know which RAM region contains kernel data,
  20.951 +			 *  so we try it repeatedly and let the resource manager
  20.952 +			 *  test it.
  20.953 +			 */
  20.954 +			request_resource(res, code_resource);
  20.955 +			request_resource(res, data_resource);
  20.956 +		}
  20.957 +	}
  20.958 +}
  20.959 +
  20.960 +/*
  20.961 + * Request address space for all standard resources
  20.962 + */
  20.963 +static void __init register_memory(unsigned long max_low_pfn)
  20.964 +{
  20.965 +	unsigned long low_mem_size;
  20.966 +
  20.967 +	if (efi_enabled)
  20.968 +		efi_initialize_iomem_resources(&code_resource, &data_resource);
  20.969 +	else
  20.970 +		legacy_init_iomem_resources(&code_resource, &data_resource);
  20.971 +
  20.972 +	/* EFI systems may still have VGA */
  20.973 +	request_graphics_resource();
  20.974 +
  20.975 +	/* request I/O space for devices used on all i[345]86 PCs */
  20.976 +	request_standard_io_resources();
  20.977 +
  20.978 +	/* Tell the PCI layer not to allocate too close to the RAM area.. */
  20.979 +	low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
  20.980 +	if (low_mem_size > pci_mem_start)
  20.981 +		pci_mem_start = low_mem_size;
  20.982 +}
  20.983 +
  20.984 +/* Use inline assembly to define this because the nops are defined 
  20.985 +   as inline assembly strings in the include files and we cannot 
  20.986 +   get them easily into strings. */
  20.987 +asm("\t.data\nintelnops: " 
  20.988 +    GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
  20.989 +    GENERIC_NOP7 GENERIC_NOP8); 
  20.990 +asm("\t.data\nk8nops: " 
  20.991 +    K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
  20.992 +    K8_NOP7 K8_NOP8); 
  20.993 +asm("\t.data\nk7nops: " 
  20.994 +    K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
  20.995 +    K7_NOP7 K7_NOP8); 
  20.996 +    
  20.997 +extern unsigned char intelnops[], k8nops[], k7nops[];
  20.998 +static unsigned char *intel_nops[ASM_NOP_MAX+1] = { 
  20.999 +     NULL,
 20.1000 +     intelnops,
 20.1001 +     intelnops + 1,
 20.1002 +     intelnops + 1 + 2,
 20.1003 +     intelnops + 1 + 2 + 3,
 20.1004 +     intelnops + 1 + 2 + 3 + 4,
 20.1005 +     intelnops + 1 + 2 + 3 + 4 + 5,
 20.1006 +     intelnops + 1 + 2 + 3 + 4 + 5 + 6,
 20.1007 +     intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
 20.1008 +}; 
 20.1009 +static unsigned char *k8_nops[ASM_NOP_MAX+1] = { 
 20.1010 +     NULL,
 20.1011 +     k8nops,
 20.1012 +     k8nops + 1,
 20.1013 +     k8nops + 1 + 2,
 20.1014 +     k8nops + 1 + 2 + 3,
 20.1015 +     k8nops + 1 + 2 + 3 + 4,
 20.1016 +     k8nops + 1 + 2 + 3 + 4 + 5,
 20.1017 +     k8nops + 1 + 2 + 3 + 4 + 5 + 6,
 20.1018 +     k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
 20.1019 +}; 
 20.1020 +static unsigned char *k7_nops[ASM_NOP_MAX+1] = { 
 20.1021 +     NULL,
 20.1022 +     k7nops,
 20.1023 +     k7nops + 1,
 20.1024 +     k7nops + 1 + 2,
 20.1025 +     k7nops + 1 + 2 + 3,
 20.1026 +     k7nops + 1 + 2 + 3 + 4,
 20.1027 +     k7nops + 1 + 2 + 3 + 4 + 5,
 20.1028 +     k7nops + 1 + 2 + 3 + 4 + 5 + 6,
 20.1029 +     k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
 20.1030 +}; 
 20.1031 +static struct nop { 
 20.1032 +     int cpuid; 
 20.1033 +     unsigned char **noptable; 
 20.1034 +} noptypes[] = { 
 20.1035 +     { X86_FEATURE_K8, k8_nops }, 
 20.1036 +     { X86_FEATURE_K7, k7_nops }, 
 20.1037 +     { -1, 0 }
 20.1038 +}; 
 20.1039 +
 20.1040 +/* Replace instructions with better alternatives for this CPU type.
 20.1041 +
 20.1042 +   This runs before SMP is initialized to avoid SMP problems with
 20.1043 +   self modifying code. This implies that assymetric systems where
 20.1044 +   APs have less capabilities than the boot processor are not handled. 
 20.1045 +   In this case boot with "noreplacement". */ 
 20.1046 +void apply_alternatives(void *start, void *end) 
 20.1047 +{ 
 20.1048 +	struct alt_instr *a; 
 20.1049 +	int diff, i, k;
 20.1050 +        unsigned char **noptable = intel_nops; 
 20.1051 +	for (i = 0; noptypes[i].cpuid >= 0; i++) { 
 20.1052 +		if (boot_cpu_has(noptypes[i].cpuid)) { 
 20.1053 +			noptable = noptypes[i].noptable;
 20.1054 +			break;
 20.1055 +		}
 20.1056 +	} 
 20.1057 +	for (a = start; (void *)a < end; a++) { 
 20.1058 +		if (!boot_cpu_has(a->cpuid))
 20.1059 +			continue;
 20.1060 +		BUG_ON(a->replacementlen > a->instrlen); 
 20.1061 +		memcpy(a->instr, a->replacement, a->replacementlen); 
 20.1062 +		diff = a->instrlen - a->replacementlen; 
 20.1063 +		/* Pad the rest with nops */
 20.1064 +		for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
 20.1065 +			k = diff;
 20.1066 +			if (k > ASM_NOP_MAX)
 20.1067 +				k = ASM_NOP_MAX;
 20.1068 +			memcpy(a->instr + i, noptable[k], k); 
 20.1069 +		} 
 20.1070 +	}
 20.1071 +} 
 20.1072 +
 20.1073 +static int no_replacement __initdata = 0; 
 20.1074 + 
 20.1075 +void __init alternative_instructions(void)
 20.1076 +{
 20.1077 +	extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
 20.1078 +	if (no_replacement) 
 20.1079 +		return;
 20.1080 +	apply_alternatives(__alt_instructions, __alt_instructions_end);
 20.1081 +}
 20.1082 +
 20.1083 +static int __init noreplacement_setup(char *s)
 20.1084 +{ 
 20.1085 +     no_replacement = 1; 
 20.1086 +     return 0; 
 20.1087 +} 
 20.1088 +
 20.1089 +__setup("noreplacement", noreplacement_setup); 
 20.1090 +
 20.1091 +/*
 20.1092 + * Determine if we were loaded by an EFI loader.  If so, then we have also been
 20.1093 + * passed the efi memmap, systab, etc., so we should use these data structures
 20.1094 + * for initialization.  Note, the efi init code path is determined by the
 20.1095 + * global efi_enabled. This allows the same kernel image to be used on existing
 20.1096 + * systems (with a traditional BIOS) as well as on EFI systems.
 20.1097 + */
 20.1098 +void __init setup_arch(char **cmdline_p)
 20.1099 +{
 20.1100 +	unsigned long max_low_pfn;
 20.1101 +
 20.1102 +	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 20.1103 +	early_cpu_init();
 20.1104 +
 20.1105 +	/*
 20.1106 +	 * FIXME: This isn't an official loader_type right
 20.1107 +	 * now but does currently work with elilo.
 20.1108 +	 * If we were configured as an EFI kernel, check to make
 20.1109 +	 * sure that we were loaded correctly from elilo and that
 20.1110 +	 * the system table is valid.  If not, then initialize normally.
 20.1111 +	 */
 20.1112 +#ifdef CONFIG_EFI
 20.1113 +	if ((LOADER_TYPE == 0x50) && EFI_SYSTAB)
 20.1114 +		efi_enabled = 1;
 20.1115 +#endif
 20.1116 +
 20.1117 + 	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
 20.1118 + 	drive_info = DRIVE_INFO;
 20.1119 + 	screen_info = SCREEN_INFO;
 20.1120 +	edid_info = EDID_INFO;
 20.1121 +	apm_info.bios = APM_BIOS_INFO;
 20.1122 +	ist_info = IST_INFO;
 20.1123 +	saved_videomode = VIDEO_MODE;
 20.1124 +	if( SYS_DESC_TABLE.length != 0 ) {
 20.1125 +		MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
 20.1126 +		machine_id = SYS_DESC_TABLE.table[0];
 20.1127 +		machine_submodel_id = SYS_DESC_TABLE.table[1];
 20.1128 +		BIOS_revision = SYS_DESC_TABLE.table[2];
 20.1129 +	}
 20.1130 +	aux_device_present = AUX_DEVICE_INFO;
 20.1131 +
 20.1132 +#ifdef CONFIG_BLK_DEV_RAM
 20.1133 +	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
 20.1134 +	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
 20.1135 +	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
 20.1136 +#endif
 20.1137 +	ARCH_SETUP
 20.1138 +	if (efi_enabled)
 20.1139 +		efi_init();
 20.1140 +	else
 20.1141 +		setup_memory_region();
 20.1142 +
 20.1143 +	copy_edd();
 20.1144 +
 20.1145 +	if (!MOUNT_ROOT_RDONLY)
 20.1146 +		root_mountflags &= ~MS_RDONLY;
 20.1147 +	init_mm.start_code = (unsigned long) _text;
 20.1148 +	init_mm.end_code = (unsigned long) _etext;
 20.1149 +	init_mm.end_data = (unsigned long) _edata;
 20.1150 +	init_mm.brk = (PFN_UP(__pa(start_info.pt_base)) + start_info.nr_pt_frames) << PAGE_SHIFT;
 20.1151 +
 20.1152 +	code_resource.start = virt_to_phys(_text);
 20.1153 +	code_resource.end = virt_to_phys(_etext)-1;
 20.1154 +	data_resource.start = virt_to_phys(_etext);
 20.1155 +	data_resource.end = virt_to_phys(_edata)-1;
 20.1156 +
 20.1157 +	parse_cmdline_early(cmdline_p);
 20.1158 +
 20.1159 +	max_low_pfn = setup_memory();
 20.1160 +
 20.1161 +	/*
 20.1162 +	 * NOTE: before this point _nobody_ is allowed to allocate
 20.1163 +	 * any memory using the bootmem allocator.
 20.1164 +	 */
 20.1165 +
 20.1166 +#ifdef CONFIG_SMP
 20.1167 +	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
 20.1168 +#endif
 20.1169 +	paging_init();
 20.1170 +
 20.1171 +#ifdef CONFIG_EARLY_PRINTK
 20.1172 +	{
 20.1173 +		char *s = strstr(*cmdline_p, "earlyprintk=");
 20.1174 +		if (s) {
 20.1175 +			extern void setup_early_printk(char *);
 20.1176 +
 20.1177 +			setup_early_printk(s);
 20.1178 +			printk("early console enabled\n");
 20.1179 +		}
 20.1180 +	}
 20.1181 +#endif
 20.1182 +
 20.1183 +
 20.1184 +	dmi_scan_machine();
 20.1185 +
 20.1186 +#ifdef CONFIG_X86_GENERICARCH
 20.1187 +	generic_apic_probe(*cmdline_p);
 20.1188 +#endif	
 20.1189 +	if (efi_enabled)
 20.1190 +		efi_map_memmap();
 20.1191 +
 20.1192 +	/*
 20.1193 +	 * Parse the ACPI tables for possible boot-time SMP configuration.
 20.1194 +	 */
 20.1195 +	acpi_boot_init();
 20.1196 +
 20.1197 +#ifdef CONFIG_X86_LOCAL_APIC
 20.1198 +	if (smp_found_config)
 20.1199 +		get_smp_config();
 20.1200 +#endif
 20.1201 +
 20.1202 +	register_memory(max_low_pfn);
 20.1203 +
 20.1204 +#ifdef CONFIG_VT
 20.1205 +#if defined(CONFIG_VGA_CONSOLE)
 20.1206 +	if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
 20.1207 +		conswitchp = &vga_con;
 20.1208 +#elif defined(CONFIG_DUMMY_CONSOLE)
 20.1209 +	conswitchp = &dummy_con;
 20.1210 +#endif
 20.1211 +#endif
 20.1212 +}
 20.1213 +
 20.1214 +#include "setup_arch_post.h"
 20.1215 +/*
 20.1216 + * Local Variables:
 20.1217 + * mode:c
 20.1218 + * c-file-style:"k&r"
 20.1219 + * c-basic-offset:8
 20.1220 + * End:
 20.1221 + */
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/signal.c	Wed Jul 14 16:41:41 2004 +0000
    21.3 @@ -0,0 +1,624 @@
    21.4 +/*
    21.5 + *  linux/arch/i386/kernel/signal.c
    21.6 + *
    21.7 + *  Copyright (C) 1991, 1992  Linus Torvalds
    21.8 + *
    21.9 + *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
   21.10 + *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
   21.11 + */
   21.12 +
   21.13 +#include <linux/sched.h>
   21.14 +#include <linux/mm.h>
   21.15 +#include <linux/smp.h>
   21.16 +#include <linux/smp_lock.h>
   21.17 +#include <linux/kernel.h>
   21.18 +#include <linux/signal.h>
   21.19 +#include <linux/errno.h>
   21.20 +#include <linux/wait.h>
   21.21 +#include <linux/unistd.h>
   21.22 +#include <linux/stddef.h>
   21.23 +#include <linux/personality.h>
   21.24 +#include <linux/suspend.h>
   21.25 +#include <linux/elf.h>
   21.26 +#include <asm/processor.h>
   21.27 +#include <asm/ucontext.h>
   21.28 +#include <asm/uaccess.h>
   21.29 +#include <asm/i387.h>
   21.30 +#include "sigframe.h"
   21.31 +
   21.32 +#define DEBUG_SIG 0
   21.33 +
   21.34 +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
   21.35 +
   21.36 +/*
   21.37 + * Atomically swap in the new signal mask, and wait for a signal.
   21.38 + */
   21.39 +asmlinkage int
   21.40 +sys_sigsuspend(int history0, int history1, old_sigset_t mask)
   21.41 +{
   21.42 +	struct pt_regs * regs = (struct pt_regs *) &history0;
   21.43 +	sigset_t saveset;
   21.44 +
   21.45 +	mask &= _BLOCKABLE;
   21.46 +	spin_lock_irq(&current->sighand->siglock);
   21.47 +	saveset = current->blocked;
   21.48 +	siginitset(&current->blocked, mask);
   21.49 +	recalc_sigpending();
   21.50 +	spin_unlock_irq(&current->sighand->siglock);
   21.51 +
   21.52 +	regs->eax = -EINTR;
   21.53 +	while (1) {
   21.54 +		current->state = TASK_INTERRUPTIBLE;
   21.55 +		schedule();
   21.56 +		if (do_signal(regs, &saveset))
   21.57 +			return -EINTR;
   21.58 +	}
   21.59 +}
   21.60 +
   21.61 +asmlinkage int
   21.62 +sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
   21.63 +{
   21.64 +	struct pt_regs * regs = (struct pt_regs *) &unewset;
   21.65 +	sigset_t saveset, newset;
   21.66 +
   21.67 +	/* XXX: Don't preclude handling different sized sigset_t's.  */
   21.68 +	if (sigsetsize != sizeof(sigset_t))
   21.69 +		return -EINVAL;
   21.70 +
   21.71 +	if (copy_from_user(&newset, unewset, sizeof(newset)))
   21.72 +		return -EFAULT;
   21.73 +	sigdelsetmask(&newset, ~_BLOCKABLE);
   21.74 +
   21.75 +	spin_lock_irq(&current->sighand->siglock);
   21.76 +	saveset = current->blocked;
   21.77 +	current->blocked = newset;
   21.78 +	recalc_sigpending();
   21.79 +	spin_unlock_irq(&current->sighand->siglock);
   21.80 +
   21.81 +	regs->eax = -EINTR;
   21.82 +	while (1) {
   21.83 +		current->state = TASK_INTERRUPTIBLE;
   21.84 +		schedule();
   21.85 +		if (do_signal(regs, &saveset))
   21.86 +			return -EINTR;
   21.87 +	}
   21.88 +}
   21.89 +
   21.90 +asmlinkage int 
   21.91 +sys_sigaction(int sig, const struct old_sigaction __user *act,
   21.92 +	      struct old_sigaction __user *oact)
   21.93 +{
   21.94 +	struct k_sigaction new_ka, old_ka;
   21.95 +	int ret;
   21.96 +
   21.97 +	if (act) {
   21.98 +		old_sigset_t mask;
   21.99 +		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
  21.100 +		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
  21.101 +		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
  21.102 +			return -EFAULT;
  21.103 +		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
  21.104 +		__get_user(mask, &act->sa_mask);
  21.105 +		siginitset(&new_ka.sa.sa_mask, mask);
  21.106 +	}
  21.107 +
  21.108 +	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  21.109 +
  21.110 +	if (!ret && oact) {
  21.111 +		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
  21.112 +		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
  21.113 +		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
  21.114 +			return -EFAULT;
  21.115 +		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
  21.116 +		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
  21.117 +	}
  21.118 +
  21.119 +	return ret;
  21.120 +}
  21.121 +
  21.122 +asmlinkage int
  21.123 +sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
  21.124 +{
  21.125 +	struct pt_regs *regs = (struct pt_regs *) &uss;
  21.126 +	return do_sigaltstack(uss, uoss, regs->esp);
  21.127 +}
  21.128 +
  21.129 +
  21.130 +/*
  21.131 + * Do a signal return; undo the signal stack.
  21.132 + */
  21.133 +
  21.134 +static int
  21.135 +restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax)
  21.136 +{
  21.137 +	unsigned int err = 0;
  21.138 +
  21.139 +	/* Always make any pending restarted system calls return -EINTR */
  21.140 +	current_thread_info()->restart_block.fn = do_no_restart_syscall;
  21.141 +
  21.142 +#define COPY(x)		err |= __get_user(regs->x, &sc->x)
  21.143 +
  21.144 +#define COPY_SEG(seg)							\
  21.145 +	{ unsigned short tmp;						\
  21.146 +	  err |= __get_user(tmp, &sc->seg);				\
  21.147 +	  regs->x##seg = tmp; }
  21.148 +
  21.149 +#define COPY_SEG_STRICT(seg)						\
  21.150 +	{ unsigned short tmp;						\
  21.151 +	  err |= __get_user(tmp, &sc->seg);				\
  21.152 +	  regs->x##seg = tmp|3; }
  21.153 +
  21.154 +#define GET_SEG(seg)							\
  21.155 +	{ unsigned short tmp;						\
  21.156 +	  err |= __get_user(tmp, &sc->seg);				\
  21.157 +	  loadsegment(seg,tmp); }
  21.158 +
  21.159 +#define	FIX_EFLAGS	(X86_EFLAGS_AC | X86_EFLAGS_OF | X86_EFLAGS_DF | \
  21.160 +			 X86_EFLAGS_TF | X86_EFLAGS_SF | X86_EFLAGS_ZF | \
  21.161 +			 X86_EFLAGS_AF | X86_EFLAGS_PF | X86_EFLAGS_CF)
  21.162 +
  21.163 +	GET_SEG(gs);
  21.164 +	GET_SEG(fs);
  21.165 +	COPY_SEG(es);
  21.166 +	COPY_SEG(ds);
  21.167 +	COPY(edi);
  21.168 +	COPY(esi);
  21.169 +	COPY(ebp);
  21.170 +	COPY(esp);
  21.171 +	COPY(ebx);
  21.172 +	COPY(edx);
  21.173 +	COPY(ecx);
  21.174 +	COPY(eip);
  21.175 +	COPY_SEG_STRICT(cs);
  21.176 +	COPY_SEG_STRICT(ss);
  21.177 +	
  21.178 +	{
  21.179 +		unsigned int tmpflags;
  21.180 +		err |= __get_user(tmpflags, &sc->eflags);
  21.181 +		regs->eflags = (regs->eflags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
  21.182 +		regs->orig_eax = -1;		/* disable syscall checks */
  21.183 +	}
  21.184 +
  21.185 +	{
  21.186 +		struct _fpstate __user * buf;
  21.187 +		err |= __get_user(buf, &sc->fpstate);
  21.188 +		if (buf) {
  21.189 +			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
  21.190 +				goto badframe;
  21.191 +			err |= restore_i387(buf);
  21.192 +		}
  21.193 +	}
  21.194 +
  21.195 +	err |= __get_user(*peax, &sc->eax);
  21.196 +	return err;
  21.197 +
  21.198 +badframe:
  21.199 +	return 1;
  21.200 +}
  21.201 +
  21.202 +asmlinkage int sys_sigreturn(unsigned long __unused)
  21.203 +{
  21.204 +	struct pt_regs *regs = (struct pt_regs *) &__unused;
  21.205 +	struct sigframe __user *frame = (struct sigframe __user *)(regs->esp - 8);
  21.206 +	sigset_t set;
  21.207 +	int eax;
  21.208 +
  21.209 +	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
  21.210 +		goto badframe;
  21.211 +	if (__get_user(set.sig[0], &frame->sc.oldmask)
  21.212 +	    || (_NSIG_WORDS > 1
  21.213 +		&& __copy_from_user(&set.sig[1], &frame->extramask,
  21.214 +				    sizeof(frame->extramask))))
  21.215 +		goto badframe;
  21.216 +
  21.217 +	sigdelsetmask(&set, ~_BLOCKABLE);
  21.218 +	spin_lock_irq(&current->sighand->siglock);
  21.219 +	current->blocked = set;
  21.220 +	recalc_sigpending();
  21.221 +	spin_unlock_irq(&current->sighand->siglock);
  21.222 +	
  21.223 +	if (restore_sigcontext(regs, &frame->sc, &eax))
  21.224 +		goto badframe;
  21.225 +	return eax;
  21.226 +
  21.227 +badframe:
  21.228 +	force_sig(SIGSEGV, current);
  21.229 +	return 0;
  21.230 +}	
  21.231 +
  21.232 +asmlinkage int sys_rt_sigreturn(unsigned long __unused)
  21.233 +{
  21.234 +	struct pt_regs *regs = (struct pt_regs *) &__unused;
  21.235 +	struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(regs->esp - 4);
  21.236 +	sigset_t set;
  21.237 +	int eax;
  21.238 +
  21.239 +	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
  21.240 +		goto badframe;
  21.241 +	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
  21.242 +		goto badframe;
  21.243 +
  21.244 +	sigdelsetmask(&set, ~_BLOCKABLE);
  21.245 +	spin_lock_irq(&current->sighand->siglock);
  21.246 +	current->blocked = set;
  21.247 +	recalc_sigpending();
  21.248 +	spin_unlock_irq(&current->sighand->siglock);
  21.249 +	
  21.250 +	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
  21.251 +		goto badframe;
  21.252 +
  21.253 +	if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->esp) == -EFAULT)
  21.254 +		goto badframe;
  21.255 +
  21.256 +	return eax;
  21.257 +
  21.258 +badframe:
  21.259 +	force_sig(SIGSEGV, current);
  21.260 +	return 0;
  21.261 +}	
  21.262 +
  21.263 +/*
  21.264 + * Set up a signal frame.
  21.265 + */
  21.266 +
  21.267 +static int
  21.268 +setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
  21.269 +		 struct pt_regs *regs, unsigned long mask)
  21.270 +{
  21.271 +	int tmp, err = 0;
  21.272 +
  21.273 +	tmp = 0;
  21.274 +	__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
  21.275 +	err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
  21.276 +	__asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
  21.277 +	err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
  21.278 +
  21.279 +	err |= __put_user(regs->xes, (unsigned int __user *)&sc->es);
  21.280 +	err |= __put_user(regs->xds, (unsigned int __user *)&sc->ds);
  21.281 +	err |= __put_user(regs->edi, &sc->edi);
  21.282 +	err |= __put_user(regs->esi, &sc->esi);
  21.283 +	err |= __put_user(regs->ebp, &sc->ebp);
  21.284 +	err |= __put_user(regs->esp, &sc->esp);
  21.285 +	err |= __put_user(regs->ebx, &sc->ebx);
  21.286 +	err |= __put_user(regs->edx, &sc->edx);
  21.287 +	err |= __put_user(regs->ecx, &sc->ecx);
  21.288 +	err |= __put_user(regs->eax, &sc->eax);
  21.289 +	err |= __put_user(current->thread.trap_no, &sc->trapno);
  21.290 +	err |= __put_user(current->thread.error_code, &sc->err);
  21.291 +	err |= __put_user(regs->eip, &sc->eip);
  21.292 +	err |= __put_user(regs->xcs, (unsigned int __user *)&sc->cs);
  21.293 +	err |= __put_user(regs->eflags, &sc->eflags);
  21.294 +	err |= __put_user(regs->esp, &sc->esp_at_signal);
  21.295 +	err |= __put_user(regs->xss, (unsigned int __user *)&sc->ss);
  21.296 +
  21.297 +	tmp = save_i387(fpstate);
  21.298 +	if (tmp < 0)
  21.299 +	  err = 1;
  21.300 +	else
  21.301 +	  err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
  21.302 +
  21.303 +	/* non-iBCS2 extensions.. */
  21.304 +	err |= __put_user(mask, &sc->oldmask);
  21.305 +	err |= __put_user(current->thread.cr2, &sc->cr2);
  21.306 +
  21.307 +	return err;
  21.308 +}
  21.309 +
  21.310 +/*
  21.311 + * Determine which stack to use..
  21.312 + */
  21.313 +static inline void __user *
  21.314 +get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
  21.315 +{
  21.316 +	unsigned long esp;
  21.317 +
  21.318 +	/* Default to using normal stack */
  21.319 +	esp = regs->esp;
  21.320 +
  21.321 +	/* This is the X/Open sanctioned signal stack switching.  */
  21.322 +	if (ka->sa.sa_flags & SA_ONSTACK) {
  21.323 +		if (sas_ss_flags(esp) == 0)
  21.324 +			esp = current->sas_ss_sp + current->sas_ss_size;
  21.325 +	}
  21.326 +
  21.327 +	/* This is the legacy signal stack switching. */
  21.328 +	else if ((regs->xss & 0xffff) != __USER_DS &&
  21.329 +		 !(ka->sa.sa_flags & SA_RESTORER) &&
  21.330 +		 ka->sa.sa_restorer) {
  21.331 +		esp = (unsigned long) ka->sa.sa_restorer;
  21.332 +	}
  21.333 +
  21.334 +	return (void __user *)((esp - frame_size) & -8ul);
  21.335 +}
  21.336 +
  21.337 +/* These symbols are defined with the addresses in the vsyscall page.
  21.338 +   See vsyscall-sigreturn.S.  */
  21.339 +extern void __kernel_sigreturn, __kernel_rt_sigreturn;
  21.340 +
  21.341 +static void setup_frame(int sig, struct k_sigaction *ka,
  21.342 +			sigset_t *set, struct pt_regs * regs)
  21.343 +{
  21.344 +	void *restorer;
  21.345 +	struct sigframe __user *frame;
  21.346 +	int err = 0;
  21.347 +
  21.348 +	frame = get_sigframe(ka, regs, sizeof(*frame));
  21.349 +
  21.350 +	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
  21.351 +		goto give_sigsegv;
  21.352 +
  21.353 +	err |= __put_user((current_thread_info()->exec_domain
  21.354 +		           && current_thread_info()->exec_domain->signal_invmap
  21.355 +		           && sig < 32
  21.356 +		           ? current_thread_info()->exec_domain->signal_invmap[sig]
  21.357 +		           : sig),
  21.358 +		          &frame->sig);
  21.359 +	if (err)
  21.360 +		goto give_sigsegv;
  21.361 +
  21.362 +	err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
  21.363 +	if (err)
  21.364 +		goto give_sigsegv;
  21.365 +
  21.366 +	if (_NSIG_WORDS > 1) {
  21.367 +		err |= __copy_to_user(&frame->extramask, &set->sig[1],
  21.368 +				      sizeof(frame->extramask));
  21.369 +	}
  21.370 +	if (err)
  21.371 +		goto give_sigsegv;
  21.372 +
  21.373 +	restorer = &__kernel_sigreturn;
  21.374 +	if (ka->sa.sa_flags & SA_RESTORER)
  21.375 +		restorer = ka->sa.sa_restorer;
  21.376 +
  21.377 +	/* Set up to return from userspace.  */
  21.378 +	err |= __put_user(restorer, &frame->pretcode);
  21.379 +	 
  21.380 +	/*
  21.381 +	 * This is popl %eax ; movl $,%eax ; int $0x80
  21.382 +	 *
  21.383 +	 * WE DO NOT USE IT ANY MORE! It's only left here for historical
  21.384 +	 * reasons and because gdb uses it as a signature to notice
  21.385 +	 * signal handler stack frames.
  21.386 +	 */
  21.387 +	err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
  21.388 +	err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
  21.389 +	err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
  21.390 +
  21.391 +	if (err)
  21.392 +		goto give_sigsegv;
  21.393 +
  21.394 +	/* Set up registers for signal handler */
  21.395 +	regs->esp = (unsigned long) frame;
  21.396 +	regs->eip = (unsigned long) ka->sa.sa_handler;
  21.397 +
  21.398 +	set_fs(USER_DS);
  21.399 +	regs->xds = __USER_DS;
  21.400 +	regs->xes = __USER_DS;
  21.401 +	regs->xss = __USER_DS;
  21.402 +	regs->xcs = __USER_CS;
  21.403 +	regs->eflags &= ~TF_MASK;
  21.404 +
  21.405 +#if DEBUG_SIG
  21.406 +	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
  21.407 +		current->comm, current->pid, frame, regs->eip, frame->pretcode);
  21.408 +#endif
  21.409 +
  21.410 +	return;
  21.411 +
  21.412 +give_sigsegv:
  21.413 +	if (sig == SIGSEGV)
  21.414 +		ka->sa.sa_handler = SIG_DFL;
  21.415 +	force_sig(SIGSEGV, current);
  21.416 +}
  21.417 +
  21.418 +static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
  21.419 +			   sigset_t *set, struct pt_regs * regs)
  21.420 +{
  21.421 +	void *restorer;
  21.422 +	struct rt_sigframe __user *frame;
  21.423 +	int err = 0;
  21.424 +
  21.425 +	frame = get_sigframe(ka, regs, sizeof(*frame));
  21.426 +
  21.427 +	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
  21.428 +		goto give_sigsegv;
  21.429 +
  21.430 +	err |= __put_user((current_thread_info()->exec_domain
  21.431 +		    	   && current_thread_info()->exec_domain->signal_invmap
  21.432 +		    	   && sig < 32
  21.433 +		    	   ? current_thread_info()->exec_domain->signal_invmap[sig]
  21.434 +			   : sig),
  21.435 +			  &frame->sig);
  21.436 +	err |= __put_user(&frame->info, &frame->pinfo);
  21.437 +	err |= __put_user(&frame->uc, &frame->puc);
  21.438 +	err |= copy_siginfo_to_user(&frame->info, info);
  21.439 +	if (err)
  21.440 +		goto give_sigsegv;
  21.441 +
  21.442 +	/* Create the ucontext.  */
  21.443 +	err |= __put_user(0, &frame->uc.uc_flags);
  21.444 +	err |= __put_user(0, &frame->uc.uc_link);
  21.445 +	err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
  21.446 +	err |= __put_user(sas_ss_flags(regs->esp),
  21.447 +			  &frame->uc.uc_stack.ss_flags);
  21.448 +	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
  21.449 +	err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
  21.450 +			        regs, set->sig[0]);
  21.451 +	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
  21.452 +	if (err)
  21.453 +		goto give_sigsegv;
  21.454 +
  21.455 +	/* Set up to return from userspace.  */
  21.456 +	restorer = &__kernel_rt_sigreturn;
  21.457 +	if (ka->sa.sa_flags & SA_RESTORER)
  21.458 +		restorer = ka->sa.sa_restorer;
  21.459 +	err |= __put_user(restorer, &frame->pretcode);
  21.460 +	 
  21.461 +	/*
  21.462 +	 * This is movl $,%eax ; int $0x80
  21.463 +	 *
  21.464 +	 * WE DO NOT USE IT ANY MORE! It's only left here for historical
  21.465 +	 * reasons and because gdb uses it as a signature to notice
  21.466 +	 * signal handler stack frames.
  21.467 +	 */
  21.468 +	err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
  21.469 +	err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
  21.470 +	err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
  21.471 +
  21.472 +	if (err)
  21.473 +		goto give_sigsegv;
  21.474 +
  21.475 +	/* Set up registers for signal handler */
  21.476 +	regs->esp = (unsigned long) frame;
  21.477 +	regs->eip = (unsigned long) ka->sa.sa_handler;
  21.478 +
  21.479 +	set_fs(USER_DS);
  21.480 +	regs->xds = __USER_DS;
  21.481 +	regs->xes = __USER_DS;
  21.482 +	regs->xss = __USER_DS;
  21.483 +	regs->xcs = __USER_CS;
  21.484 +	regs->eflags &= ~TF_MASK;
  21.485 +
  21.486 +#if DEBUG_SIG
  21.487 +	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
  21.488 +		current->comm, current->pid, frame, regs->eip, frame->pretcode);
  21.489 +#endif
  21.490 +
  21.491 +	return;
  21.492 +
  21.493 +give_sigsegv:
  21.494 +	if (sig == SIGSEGV)
  21.495 +		ka->sa.sa_handler = SIG_DFL;
  21.496 +	force_sig(SIGSEGV, current);
  21.497 +}
  21.498 +
  21.499 +/*
  21.500 + * OK, we're invoking a handler
  21.501 + */	
  21.502 +
  21.503 +static void
  21.504 +handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
  21.505 +	struct pt_regs * regs)
  21.506 +{
  21.507 +	struct k_sigaction *ka = &current->sighand->action[sig-1];
  21.508 +
  21.509 +	/* Are we from a system call? */
  21.510 +	if (regs->orig_eax >= 0) {
  21.511 +		/* If so, check system call restarting.. */
  21.512 +		switch (regs->eax) {
  21.513 +		        case -ERESTART_RESTARTBLOCK:
  21.514 +			case -ERESTARTNOHAND:
  21.515 +				regs->eax = -EINTR;
  21.516 +				break;
  21.517 +
  21.518 +			case -ERESTARTSYS:
  21.519 +				if (!(ka->sa.sa_flags & SA_RESTART)) {
  21.520 +					regs->eax = -EINTR;
  21.521 +					break;
  21.522 +				}
  21.523 +			/* fallthrough */
  21.524 +			case -ERESTARTNOINTR:
  21.525 +				regs->eax = regs->orig_eax;
  21.526 +				regs->eip -= 2;
  21.527 +		}
  21.528 +	}
  21.529 +
  21.530 +	/* Set up the stack frame */
  21.531 +	if (ka->sa.sa_flags & SA_SIGINFO)
  21.532 +		setup_rt_frame(sig, ka, info, oldset, regs);
  21.533 +	else
  21.534 +		setup_frame(sig, ka, oldset, regs);
  21.535 +
  21.536 +	if (ka->sa.sa_flags & SA_ONESHOT)
  21.537 +		ka->sa.sa_handler = SIG_DFL;
  21.538 +
  21.539 +	if (!(ka->sa.sa_flags & SA_NODEFER)) {
  21.540 +		spin_lock_irq(&current->sighand->siglock);
  21.541 +		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
  21.542 +		sigaddset(&current->blocked,sig);
  21.543 +		recalc_sigpending();
  21.544 +		spin_unlock_irq(&current->sighand->siglock);
  21.545 +	}
  21.546 +}
  21.547 +
  21.548 +/*
  21.549 + * Note that 'init' is a special process: it doesn't get signals it doesn't
  21.550 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
  21.551 + * mistake.
  21.552 + */
  21.553 +int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
  21.554 +{
  21.555 +	siginfo_t info;
  21.556 +	int signr;
  21.557 +
  21.558 +	/*
  21.559 +	 * We want the common case to go fast, which
  21.560 +	 * is why we may in certain cases get here from
  21.561 +	 * kernel mode. Just return without doing anything
  21.562 +	 * if so.
  21.563 +	 */
  21.564 +	if ((regs->xcs & 2) != 2)
  21.565 +		return 1;
  21.566 +
  21.567 +	if (current->flags & PF_FREEZE) {
  21.568 +		refrigerator(0);
  21.569 +		goto no_signal;
  21.570 +	}
  21.571 +
  21.572 +	if (!oldset)
  21.573 +		oldset = &current->blocked;
  21.574 +
  21.575 +	signr = get_signal_to_deliver(&info, regs, NULL);
  21.576 +	if (signr > 0) {
  21.577 +		/* Reenable any watchpoints before delivering the
  21.578 +		 * signal to user space. The processor register will
  21.579 +		 * have been cleared if the watchpoint triggered
  21.580 +		 * inside the kernel.
  21.581 +		 */
  21.582 +		if (current->thread.debugreg[7])
  21.583 +			HYPERVISOR_set_debugreg(7,
  21.584 +						current->thread.debugreg[7]);
  21.585 +
  21.586 +		/* Whee!  Actually deliver the signal.  */
  21.587 +		handle_signal(signr, &info, oldset, regs);
  21.588 +		return 1;
  21.589 +	}
  21.590 +
  21.591 + no_signal:
  21.592 +	/* Did we come from a system call? */
  21.593 +	if (regs->orig_eax >= 0) {
  21.594 +		/* Restart the system call - no handlers present */
  21.595 +		if (regs->eax == -ERESTARTNOHAND ||
  21.596 +		    regs->eax == -ERESTARTSYS ||
  21.597 +		    regs->eax == -ERESTARTNOINTR) {
  21.598 +			regs->eax = regs->orig_eax;
  21.599 +			regs->eip -= 2;
  21.600 +		}
  21.601 +		if (regs->eax == -ERESTART_RESTARTBLOCK){
  21.602 +			regs->eax = __NR_restart_syscall;
  21.603 +			regs->eip -= 2;
  21.604 +		}
  21.605 +	}
  21.606 +	return 0;
  21.607 +}
  21.608 +
  21.609 +/*
  21.610 + * notification of userspace execution resumption
  21.611 + * - triggered by current->work.notify_resume
  21.612 + */
  21.613 +__attribute__((regparm(3)))
  21.614 +void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
  21.615 +		      __u32 thread_info_flags)
  21.616 +{
  21.617 +	/* Pending single-step? */
  21.618 +	if (thread_info_flags & _TIF_SINGLESTEP) {
  21.619 +		regs->eflags |= TF_MASK;
  21.620 +		clear_thread_flag(TIF_SINGLESTEP);
  21.621 +	}
  21.622 +	/* deal with pending signal delivery */
  21.623 +	if (thread_info_flags & _TIF_SIGPENDING)
  21.624 +		do_signal(regs,oldset);
  21.625 +	
  21.626 +	clear_thread_flag(TIF_IRET);
  21.627 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/sysenter.c	Wed Jul 14 16:41:41 2004 +0000
    22.3 @@ -0,0 +1,65 @@
    22.4 +/*
    22.5 + * linux/arch/i386/kernel/sysenter.c
    22.6 + *
    22.7 + * (C) Copyright 2002 Linus Torvalds
    22.8 + *
    22.9 + * This file contains the needed initializations to support sysenter.
   22.10 + */
   22.11 +
   22.12 +#include <linux/init.h>
   22.13 +#include <linux/smp.h>
   22.14 +#include <linux/thread_info.h>
   22.15 +#include <linux/sched.h>
   22.16 +#include <linux/gfp.h>
   22.17 +#include <linux/string.h>
   22.18 +#include <linux/elf.h>
   22.19 +
   22.20 +#include <asm/cpufeature.h>
   22.21 +#include <asm/msr.h>
   22.22 +#include <asm/pgtable.h>
   22.23 +#include <asm/unistd.h>
   22.24 +
   22.25 +extern asmlinkage void sysenter_entry(void);
   22.26 +
   22.27 +void enable_sep_cpu(void *info)
   22.28 +{
   22.29 +	int cpu = get_cpu();
   22.30 +	struct tss_struct *tss = init_tss + cpu;
   22.31 +
   22.32 +	tss->ss1 = __KERNEL_CS;
   22.33 +	tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
   22.34 +	wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
   22.35 +	wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
   22.36 +	wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
   22.37 +	put_cpu();	
   22.38 +}
   22.39 +
   22.40 +/*
   22.41 + * These symbols are defined by vsyscall.o to mark the bounds
   22.42 + * of the ELF DSO images included therein.
   22.43 + */
   22.44 +extern const char vsyscall_int80_start, vsyscall_int80_end;
   22.45 +extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
   22.46 +
   22.47 +static int __init sysenter_setup(void)
   22.48 +{
   22.49 +	unsigned long page = get_zeroed_page(GFP_ATOMIC);
   22.50 +
   22.51 +	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY);
   22.52 +
   22.53 +	if (1 /* XXXcl not yet */ || !boot_cpu_has(X86_FEATURE_SEP)) {
   22.54 +		memcpy((void *) page,
   22.55 +		       &vsyscall_int80_start,
   22.56 +		       &vsyscall_int80_end - &vsyscall_int80_start);
   22.57 +		return 0;
   22.58 +	}
   22.59 +
   22.60 +	memcpy((void *) page,
   22.61 +	       &vsyscall_sysenter_start,
   22.62 +	       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
   22.63 +
   22.64 +	on_each_cpu(enable_sep_cpu, NULL, 1, 1);
   22.65 +	return 0;
   22.66 +}
   22.67 +
   22.68 +__initcall(sysenter_setup);
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c	Wed Jul 14 16:41:41 2004 +0000
    23.3 @@ -0,0 +1,412 @@
    23.4 +/*
    23.5 + *  linux/arch/i386/kernel/time.c
    23.6 + *
    23.7 + *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
    23.8 + *
    23.9 + * This file contains the PC-specific time handling details:
   23.10 + * reading the RTC at bootup, etc..
   23.11 + * 1994-07-02    Alan Modra
   23.12 + *	fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
   23.13 + * 1995-03-26    Markus Kuhn
   23.14 + *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
   23.15 + *      precision CMOS clock update
   23.16 + * 1996-05-03    Ingo Molnar
   23.17 + *      fixed time warps in do_[slow|fast]_gettimeoffset()
   23.18 + * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
   23.19 + *		"A Kernel Model for Precision Timekeeping" by Dave Mills
   23.20 + * 1998-09-05    (Various)
   23.21 + *	More robust do_fast_gettimeoffset() algorithm implemented
   23.22 + *	(works with APM, Cyrix 6x86MX and Centaur C6),
   23.23 + *	monotonic gettimeofday() with fast_get_timeoffset(),
   23.24 + *	drift-proof precision TSC calibration on boot
   23.25 + *	(C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
   23.26 + *	Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
   23.27 + *	ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
   23.28 + * 1998-12-16    Andrea Arcangeli
   23.29 + *	Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
   23.30 + *	because was not accounting lost_ticks.
   23.31 + * 1998-12-24 Copyright (C) 1998  Andrea Arcangeli
   23.32 + *	Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
   23.33 + *	serialize accesses to xtime/lost_ticks).
   23.34 + */
   23.35 +
   23.36 +#include <linux/errno.h>
   23.37 +#include <linux/sched.h>
   23.38 +#include <linux/kernel.h>
   23.39 +#include <linux/param.h>
   23.40 +#include <linux/string.h>
   23.41 +#include <linux/mm.h>
   23.42 +#include <linux/interrupt.h>
   23.43 +#include <linux/time.h>
   23.44 +#include <linux/delay.h>
   23.45 +#include <linux/init.h>
   23.46 +#include <linux/smp.h>
   23.47 +#include <linux/module.h>
   23.48 +#include <linux/sysdev.h>
   23.49 +#include <linux/bcd.h>
   23.50 +#include <linux/efi.h>
   23.51 +
   23.52 +#include <asm/io.h>
   23.53 +#include <asm/smp.h>
   23.54 +#include <asm/irq.h>
   23.55 +#include <asm/msr.h>
   23.56 +#include <asm/delay.h>
   23.57 +#include <asm/mpspec.h>
   23.58 +#include <asm/uaccess.h>
   23.59 +#include <asm/processor.h>
   23.60 +#include <asm/timer.h>
   23.61 +
   23.62 +#include "mach_time.h"
   23.63 +
   23.64 +#include <linux/timex.h>
   23.65 +#include <linux/config.h>
   23.66 +
   23.67 +#include <asm/hpet.h>
   23.68 +
   23.69 +#include <asm/arch_hooks.h>
   23.70 +
   23.71 +#include "io_ports.h"
   23.72 +
   23.73 +extern spinlock_t i8259A_lock;
   23.74 +int pit_latch_buggy;              /* extern */
   23.75 +
   23.76 +#include "do_timer.h"
   23.77 +
   23.78 +u64 jiffies_64 = INITIAL_JIFFIES;
   23.79 +
   23.80 +EXPORT_SYMBOL(jiffies_64);
   23.81 +
   23.82 +unsigned long cpu_khz;	/* Detected as we calibrate the TSC */
   23.83 +
   23.84 +extern unsigned long wall_jiffies;
   23.85 +
   23.86 +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
   23.87 +
   23.88 +spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
   23.89 +EXPORT_SYMBOL(i8253_lock);
   23.90 +
   23.91 +struct timer_opts *cur_timer = &timer_none;
   23.92 +
   23.93 +/*
   23.94 + * This version of gettimeofday has microsecond resolution
   23.95 + * and better than microsecond precision on fast x86 machines with TSC.
   23.96 + */
   23.97 +void do_gettimeofday(struct timeval *tv)
   23.98 +{
   23.99 +	unsigned long seq;
  23.100 +	unsigned long usec, sec;
  23.101 +	unsigned long max_ntp_tick;
  23.102 +
  23.103 +	do {
  23.104 +		unsigned long lost;
  23.105 +
  23.106 +		seq = read_seqbegin(&xtime_lock);
  23.107 +
  23.108 +		usec = cur_timer->get_offset();
  23.109 +		lost = jiffies - wall_jiffies;
  23.110 +
  23.111 +		/*
  23.112 +		 * If time_adjust is negative then NTP is slowing the clock
  23.113 +		 * so make sure not to go into next possible interval.
  23.114 +		 * Better to lose some accuracy than have time go backwards..
  23.115 +		 */
  23.116 +		if (unlikely(time_adjust < 0)) {
  23.117 +			max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
  23.118 +			usec = min(usec, max_ntp_tick);
  23.119 +
  23.120 +			if (lost)
  23.121 +				usec += lost * max_ntp_tick;
  23.122 +		}
  23.123 +		else if (unlikely(lost))
  23.124 +			usec += lost * (USEC_PER_SEC / HZ);
  23.125 +
  23.126 +		sec = xtime.tv_sec;
  23.127 +		usec += (xtime.tv_nsec / 1000);
  23.128 +	} while (read_seqretry(&xtime_lock, seq));
  23.129 +
  23.130 +	while (usec >= 1000000) {
  23.131 +		usec -= 1000000;
  23.132 +		sec++;
  23.133 +	}
  23.134 +
  23.135 +	tv->tv_sec = sec;
  23.136 +	tv->tv_usec = usec;
  23.137 +}
  23.138 +
  23.139 +EXPORT_SYMBOL(do_gettimeofday);
  23.140 +
  23.141 +int do_settimeofday(struct timespec *tv)
  23.142 +{
  23.143 +	time_t wtm_sec, sec = tv->tv_sec;
  23.144 +	long wtm_nsec, nsec = tv->tv_nsec;
  23.145 +
  23.146 +	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
  23.147 +		return -EINVAL;
  23.148 +
  23.149 +	write_seqlock_irq(&xtime_lock);
  23.150 +	/*
  23.151 +	 * This is revolting. We need to set "xtime" correctly. However, the
  23.152 +	 * value in this location is the value at the most recent update of
  23.153 +	 * wall time.  Discover what correction gettimeofday() would have
  23.154 +	 * made, and then undo it!
  23.155 +	 */
  23.156 +	nsec -= cur_timer->get_offset() * NSEC_PER_USEC;
  23.157 +	nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
  23.158 +
  23.159 +	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
  23.160 +	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
  23.161 +
  23.162 +	set_normalized_timespec(&xtime, sec, nsec);
  23.163 +	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
  23.164 +
  23.165 +	time_adjust = 0;		/* stop active adjtime() */
  23.166 +	time_status |= STA_UNSYNC;
  23.167 +	time_maxerror = NTP_PHASE_LIMIT;
  23.168 +	time_esterror = NTP_PHASE_LIMIT;
  23.169 +	write_sequnlock_irq(&xtime_lock);
  23.170 +	clock_was_set();
  23.171 +	return 0;
  23.172 +}
  23.173 +
  23.174 +EXPORT_SYMBOL(do_settimeofday);
  23.175 +
  23.176 +#if 0
  23.177 +static int set_rtc_mmss(unsigned long nowtime)
  23.178 +{
  23.179 +	int retval;
  23.180 +
  23.181 +	/* gets recalled with irq locally disabled */
  23.182 +	spin_lock(&rtc_lock);
  23.183 +	if (efi_enabled)
  23.184 +		retval = efi_set_rtc_mmss(nowtime);
  23.185 +	else
  23.186 +		retval = mach_set_rtc_mmss(nowtime);
  23.187 +	spin_unlock(&rtc_lock);
  23.188 +
  23.189 +	return retval;
  23.190 +}
  23.191 +
  23.192 +/* last time the cmos clock got updated */
  23.193 +static long last_rtc_update;
  23.194 +#endif
  23.195 +
  23.196 +int timer_ack;
  23.197 +
  23.198 +/* monotonic_clock(): returns # of nanoseconds passed since time_init()
  23.199 + *		Note: This function is required to return accurate
  23.200 + *		time even in the absence of multiple timer ticks.
  23.201 + */
  23.202 +unsigned long long monotonic_clock(void)
  23.203 +{
  23.204 +	return cur_timer->monotonic_clock();
  23.205 +}
  23.206 +EXPORT_SYMBOL(monotonic_clock);
  23.207 +
  23.208 +
  23.209 +/*
  23.210 + * timer_interrupt() needs to keep up the real-time clock,
  23.211 + * as well as call the "do_timer()" routine every clocktick
  23.212 + */
  23.213 +static inline void do_timer_interrupt(int irq, void *dev_id,
  23.214 +					struct pt_regs *regs)
  23.215 +{
  23.216 +#ifdef CONFIG_X86_IO_APIC
  23.217 +	if (timer_ack) {
  23.218 +		/*
  23.219 +		 * Subtle, when I/O APICs are used we have to ack timer IRQ
  23.220 +		 * manually to reset the IRR bit for do_slow_gettimeoffset().
  23.221 +		 * This will also deassert NMI lines for the watchdog if run
  23.222 +		 * on an 82489DX-based system.
  23.223 +		 */
  23.224 +		spin_lock(&i8259A_lock);
  23.225 +		outb(0x0c, PIC_MASTER_OCW3);
  23.226 +		/* Ack the IRQ; AEOI will end it automatically. */
  23.227 +		inb(PIC_MASTER_POLL);
  23.228 +		spin_unlock(&i8259A_lock);
  23.229 +	}
  23.230 +#endif
  23.231 +
  23.232 +	do_timer_interrupt_hook(regs);
  23.233 +
  23.234 +#if 0				/* XEN PRIV */
  23.235 +	/*
  23.236 +	 * If we have an externally synchronized Linux clock, then update
  23.237 +	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
  23.238 +	 * called as close as possible to 500 ms before the new second starts.
  23.239 +	 */
  23.240 +	if ((time_status & STA_UNSYNC) == 0 &&
  23.241 +	    xtime.tv_sec > last_rtc_update + 660 &&
  23.242 +	    (xtime.tv_nsec / 1000)
  23.243 +			>= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
  23.244 +	    (xtime.tv_nsec / 1000)
  23.245 +			<= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2) {
  23.246 +		/* horrible...FIXME */
  23.247 +		if (efi_enabled) {
  23.248 +	 		if (efi_set_rtc_mmss(xtime.tv_sec) == 0)
  23.249 +				last_rtc_update = xtime.tv_sec;
  23.250 +			else
  23.251 +				last_rtc_update = xtime.tv_sec - 600;
  23.252 +		} else if (set_rtc_mmss(xtime.tv_sec) == 0)
  23.253 +			last_rtc_update = xtime.tv_sec;
  23.254 +		else
  23.255 +			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
  23.256 +	}
  23.257 +#endif
  23.258 +
  23.259 +#ifdef CONFIG_MCA
  23.260 +	if( MCA_bus ) {
  23.261 +		/* The PS/2 uses level-triggered interrupts.  You can't
  23.262 +		turn them off, nor would you want to (any attempt to
  23.263 +		enable edge-triggered interrupts usually gets intercepted by a
  23.264 +		special hardware circuit).  Hence we have to acknowledge
  23.265 +		the timer interrupt.  Through some incredibly stupid
  23.266 +		design idea, the reset for IRQ 0 is done by setting the
  23.267 +		high bit of the PPI port B (0x61).  Note that some PS/2s,
  23.268 +		notably the 55SX, work fine if this is removed.  */
  23.269 +
  23.270 +		irq = inb_p( 0x61 );	/* read the current state */
  23.271 +		outb_p( irq|0x80, 0x61 );	/* reset the IRQ */
  23.272 +	}
  23.273 +#endif
  23.274 +}
  23.275 +
  23.276 +/*
  23.277 + * This is the same as the above, except we _also_ save the current
  23.278 + * Time Stamp Counter value at the time of the timer interrupt, so that
  23.279 + * we later on can estimate the time of day more exactly.
  23.280 + */
  23.281 +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  23.282 +{
  23.283 +	/*
  23.284 +	 * Here we are in the timer irq handler. We just have irqs locally
  23.285 +	 * disabled but we don't know if the timer_bh is running on the other
  23.286 +	 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
  23.287 +	 * the irq version of write_lock because as just said we have irq
  23.288 +	 * locally disabled. -arca
  23.289 +	 */
  23.290 +	write_seqlock(&xtime_lock);
  23.291 +
  23.292 +	cur_timer->mark_offset();
  23.293 + 
  23.294 +	if (regs)		/* XXXcl check regs in do_timer_interrupt */
  23.295 +		do_timer_interrupt(irq, NULL, regs);
  23.296 +
  23.297 +	write_sequnlock(&xtime_lock);
  23.298 +	return IRQ_HANDLED;
  23.299 +}
  23.300 +
  23.301 +/* not static: needed by APM */
  23.302 +unsigned long get_cmos_time(void)
  23.303 +{
  23.304 +	unsigned long retval;
  23.305 +
  23.306 +	spin_lock(&rtc_lock);
  23.307 +
  23.308 +	if (efi_enabled)
  23.309 +		retval = efi_get_time();
  23.310 +	else
  23.311 +		retval = mach_get_cmos_time();
  23.312 +
  23.313 +	spin_unlock(&rtc_lock);
  23.314 +
  23.315 +	return retval;
  23.316 +}
  23.317 +
  23.318 +static long clock_cmos_diff;
  23.319 +
  23.320 +static int time_suspend(struct sys_device *dev, u32 state)
  23.321 +{
  23.322 +	/*
  23.323 +	 * Estimate time zone so that set_time can update the clock
  23.324 +	 */
  23.325 +	clock_cmos_diff = -get_cmos_time();
  23.326 +	clock_cmos_diff += get_seconds();
  23.327 +	return 0;
  23.328 +}
  23.329 +
  23.330 +static int time_resume(struct sys_device *dev)
  23.331 +{
  23.332 +	unsigned long sec = get_cmos_time() + clock_cmos_diff;
  23.333 +	write_seqlock_irq(&xtime_lock);
  23.334 +	xtime.tv_sec = sec;
  23.335 +	xtime.tv_nsec = 0;
  23.336 +	write_sequnlock_irq(&xtime_lock);
  23.337 +	return 0;
  23.338 +}
  23.339 +
  23.340 +static struct sysdev_class pit_sysclass = {
  23.341 +	.resume = time_resume,
  23.342 +	.suspend = time_suspend,
  23.343 +	set_kset_name("pit"),
  23.344 +};
  23.345 +
  23.346 +
  23.347 +/* XXX this driverfs stuff should probably go elsewhere later -john */
  23.348 +static struct sys_device device_i8253 = {
  23.349 +	.id	= 0,
  23.350 +	.cls	= &pit_sysclass,
  23.351 +};
  23.352 +
  23.353 +static int time_init_device(void)
  23.354 +{
  23.355 +	int error = sysdev_class_register(&pit_sysclass);
  23.356 +	if (!error)
  23.357 +		error = sysdev_register(&device_i8253);
  23.358 +	return error;
  23.359 +}
  23.360 +
  23.361 +device_initcall(time_init_device);
  23.362 +
  23.363 +#ifdef CONFIG_HPET_TIMER
  23.364 +extern void (*late_time_init)(void);
  23.365 +/* Duplicate of time_init() below, with hpet_enable part added */
  23.366 +void __init hpet_time_init(void)
  23.367 +{
  23.368 +	xtime.tv_sec = get_cmos_time();
  23.369 +	wall_to_monotonic.tv_sec = -xtime.tv_sec;
  23.370 +	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
  23.371 +	wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
  23.372 +
  23.373 +	if (hpet_enable() >= 0) {
  23.374 +		printk("Using HPET for base-timer\n");
  23.375 +	}
  23.376 +
  23.377 +	cur_timer = select_timer();
  23.378 +	printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
  23.379 +
  23.380 +	time_init_hook();
  23.381 +}
  23.382 +#endif
  23.383 +
  23.384 +/* Dynamically-mapped IRQ. */
  23.385 +static int time_irq;
  23.386 +
  23.387 +static struct irqaction irq_timer = {
  23.388 +	timer_interrupt, SA_INTERRUPT, 0, "timer",
  23.389 +	NULL, NULL
  23.390 +};
  23.391 +
  23.392 +void __init time_init(void)
  23.393 +{
  23.394 +#ifdef CONFIG_HPET_TIMER
  23.395 +	if (is_hpet_capable()) {
  23.396 +		/*
  23.397 +		 * HPET initialization needs to do memory-mapped io. So, let
  23.398 +		 * us do a late initialization after mem_init().
  23.399 +		 */
  23.400 +		late_time_init = hpet_time_init;
  23.401 +		return;
  23.402 +	}
  23.403 +#endif
  23.404 +	xtime.tv_sec = HYPERVISOR_shared_info->wc_sec;
  23.405 +	wall_to_monotonic.tv_sec = -xtime.tv_sec;
  23.406 +	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
  23.407 +	wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
  23.408 +
  23.409 +	cur_timer = select_timer();
  23.410 +	printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
  23.411 +
  23.412 +	time_irq  = bind_virq_to_irq(VIRQ_TIMER);
  23.413 +
  23.414 +	(void)setup_irq(time_irq, &irq_timer);
  23.415 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/Makefile	Wed Jul 14 16:41:41 2004 +0000
    24.3 @@ -0,0 +1,17 @@
    24.4 +#
    24.5 +# Makefile for x86 timers
    24.6 +#
    24.7 +
    24.8 +XENARCH	:= $(subst ",,$(CONFIG_XENARCH))
    24.9 +
   24.10 +obj-y :=	timer_tsc.o
   24.11 +c-obj-y :=	timer.o common.o timer_none.o timer_pit.o
   24.12 +
   24.13 +c-link	:=
   24.14 +
   24.15 +$(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)):
   24.16 +	@ln -fsn $(srctree)/arch/i386/kernel/timers/$(notdir $@) $@
   24.17 +
   24.18 +obj-y	+= $(c-obj-y)
   24.19 +
   24.20 +clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link))
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c	Wed Jul 14 16:41:41 2004 +0000
    25.3 @@ -0,0 +1,528 @@
    25.4 +/*
    25.5 + * This code largely moved from arch/i386/kernel/time.c.
    25.6 + * See comments there for proper credits.
    25.7 + */
    25.8 +
    25.9 +#include <linux/spinlock.h>
   25.10 +#include <linux/init.h>
   25.11 +#include <linux/timex.h>
   25.12 +#include <linux/errno.h>
   25.13 +#include <linux/cpufreq.h>
   25.14 +#include <linux/string.h>
   25.15 +#include <linux/jiffies.h>
   25.16 +
   25.17 +#include <asm/timer.h>
   25.18 +#include <asm/io.h>
   25.19 +/* processor.h for distable_tsc flag */
   25.20 +#include <asm/processor.h>
   25.21 +
   25.22 +#include "io_ports.h"
   25.23 +#include "mach_timer.h"
   25.24 +
   25.25 +#include <asm/hpet.h>
   25.26 +
   25.27 +#ifdef CONFIG_HPET_TIMER
   25.28 +static unsigned long hpet_usec_quotient;
   25.29 +static unsigned long hpet_last;
   25.30 +struct timer_opts timer_tsc;
   25.31 +#endif
   25.32 +
   25.33 +static inline void cpufreq_delayed_get(void);
   25.34 +
   25.35 +int tsc_disable __initdata = 0;
   25.36 +
   25.37 +extern spinlock_t i8253_lock;
   25.38 +
   25.39 +static int use_tsc;
   25.40 +/* Number of usecs that the last interrupt was delayed */
   25.41 +static int delay_at_last_interrupt;
   25.42 +
   25.43 +static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
   25.44 +static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */
   25.45 +static unsigned long long monotonic_base;
   25.46 +static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
   25.47 +
   25.48 +/* convert from cycles(64bits) => nanoseconds (64bits)
   25.49 + *  basic equation:
   25.50 + *		ns = cycles / (freq / ns_per_sec)
   25.51 + *		ns = cycles * (ns_per_sec / freq)
   25.52 + *		ns = cycles * (10^9 / (cpu_mhz * 10^6))
   25.53 + *		ns = cycles * (10^3 / cpu_mhz)
   25.54 + *
   25.55 + *	Then we use scaling math (suggested by george@mvista.com) to get:
   25.56 + *		ns = cycles * (10^3 * SC / cpu_mhz) / SC
   25.57 + *		ns = cycles * cyc2ns_scale / SC
   25.58 + *
   25.59 + *	And since SC is a constant power of two, we can convert the div
   25.60 + *  into a shift.   
   25.61 + *			-johnstul@us.ibm.com "math is hard, lets go shopping!"
   25.62 + */
   25.63 +static unsigned long cyc2ns_scale; 
   25.64 +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
   25.65 +
   25.66 +static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
   25.67 +{
   25.68 +	cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
   25.69 +}
   25.70 +
   25.71 +static inline unsigned long long cycles_2_ns(unsigned long long cyc)
   25.72 +{
   25.73 +	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
   25.74 +}
   25.75 +
   25.76 +
   25.77 +#if 0
   25.78 +static int count2; /* counter for mark_offset_tsc() */
   25.79 +#endif
   25.80 +
   25.81 +/* Cached *multiplier* to convert TSC counts to microseconds.
   25.82 + * (see the equation below).
   25.83 + * Equal to 2^32 * (1 / (clocks per usec) ).
   25.84 + * Initialized in time_init.
   25.85 + */
   25.86 +static unsigned long fast_gettimeoffset_quotient;
   25.87 +
   25.88 +
   25.89 +/* These are peridically updated in shared_info, and then copied here. */
   25.90 +static u32 shadow_tsc_stamp;
   25.91 +static u64 shadow_system_time;
   25.92 +static u32 shadow_time_version;
   25.93 +static struct timeval shadow_tv;
   25.94 +
   25.95 +/*
   25.96 + * Reads a consistent set of time-base values from Xen, into a shadow data
   25.97 + * area. Must be called with the xtime_lock held for writing.
   25.98 + */
   25.99 +static void __get_time_values_from_xen(void)
  25.100 +{
  25.101 +	do {
  25.102 +		shadow_time_version = HYPERVISOR_shared_info->time_version2;
  25.103 +		rmb();
  25.104 +		shadow_tv.tv_sec    = HYPERVISOR_shared_info->wc_sec;
  25.105 +		shadow_tv.tv_usec   = HYPERVISOR_shared_info->wc_usec;
  25.106 +		shadow_tsc_stamp    = HYPERVISOR_shared_info->tsc_timestamp.tsc_bits;
  25.107 +		shadow_system_time  = HYPERVISOR_shared_info->system_time;
  25.108 +		rmb();
  25.109 +	}
  25.110 +	while (shadow_time_version != HYPERVISOR_shared_info->time_version1);
  25.111 +}
  25.112 +
  25.113 +#define TIME_VALUES_UP_TO_DATE \
  25.114 +	(shadow_time_version == HYPERVISOR_shared_info->time_version2)
  25.115 +
  25.116 +
  25.117 +static unsigned long get_offset_tsc(void)
  25.118 +{
  25.119 +	register unsigned long eax, edx;
  25.120 +
  25.121 +	/* Read the Time Stamp Counter */
  25.122 +
  25.123 +	rdtsc(eax,edx);
  25.124 +
  25.125 +	/* .. relative to previous jiffy (32 bits is enough) */
  25.126 +	eax -= last_tsc_low;	/* tsc_low delta */
  25.127 +
  25.128 +	/*
  25.129 +         * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient
  25.130 +         *             = (tsc_low delta) * (usecs_per_clock)
  25.131 +         *             = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy)
  25.132 +	 *
  25.133 +	 * Using a mull instead of a divl saves up to 31 clock cycles
  25.134 +	 * in the critical path.
  25.135 +         */
  25.136 +
  25.137 +	__asm__("mull %2"
  25.138 +		:"=a" (eax), "=d" (edx)
  25.139 +		:"rm" (fast_gettimeoffset_quotient),
  25.140 +		 "0" (eax));
  25.141 +
  25.142 +	/* our adjusted time offset in microseconds */
  25.143 +	return delay_at_last_interrupt + edx;
  25.144 +}
  25.145 +
  25.146 +static unsigned long long monotonic_clock_tsc(void)
  25.147 +{
  25.148 +	unsigned long long last_offset, this_offset, base;
  25.149 +	unsigned seq;
  25.150 +	
  25.151 +	/* atomically read monotonic base & last_offset */
  25.152 +	do {
  25.153 +		seq = read_seqbegin(&monotonic_lock);
  25.154 +		last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
  25.155 +		base = monotonic_base;
  25.156 +	} while (read_seqretry(&monotonic_lock, seq));
  25.157 +
  25.158 +	/* Read the Time Stamp Counter */
  25.159 +	rdtscll(this_offset);
  25.160 +
  25.161 +	/* return the value in ns */
  25.162 +	return base + cycles_2_ns(this_offset - last_offset);
  25.163 +}
  25.164 +
  25.165 +/*
  25.166 + * Scheduler clock - returns current time in nanosec units.
  25.167 + */
  25.168 +unsigned long long sched_clock(void)
  25.169 +{
  25.170 +	unsigned long long this_offset;
  25.171 +
  25.172 +	/*
  25.173 +	 * In the NUMA case we dont use the TSC as they are not
  25.174 +	 * synchronized across all CPUs.
  25.175 +	 */
  25.176 +#ifndef CONFIG_NUMA
  25.177 +	if (!use_tsc)
  25.178 +#endif
  25.179 +		/* no locking but a rare wrong value is not a big deal */
  25.180 +		return jiffies_64 * (1000000000 / HZ);
  25.181 +
  25.182 +	/* Read the Time Stamp Counter */
  25.183 +	rdtscll(this_offset);
  25.184 +
  25.185 +	/* return the value in ns */
  25.186 +	return cycles_2_ns(this_offset);
  25.187 +}
  25.188 +
  25.189 +
  25.190 +static void mark_offset_tsc(void)
  25.191 +{
  25.192 +	unsigned long lost,delay;
  25.193 +	unsigned long delta = last_tsc_low;
  25.194 +#if 0
  25.195 +	int count;
  25.196 +	int countmp;
  25.197 +	static int count1 = 0;
  25.198 +#endif
  25.199 +	unsigned long long this_offset, last_offset;
  25.200 +	static int lost_count = 0;
  25.201 +	
  25.202 +	write_seqlock(&monotonic_lock);
  25.203 +	last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
  25.204 +	/*
  25.205 +	 * It is important that these two operations happen almost at
  25.206 +	 * the same time. We do the RDTSC stuff first, since it's
  25.207 +	 * faster. To avoid any inconsistencies, we need interrupts
  25.208 +	 * disabled locally.
  25.209 +	 */
  25.210 +
  25.211 +	/*
  25.212 +	 * Interrupts are just disabled locally since the timer irq
  25.213 +	 * has the SA_INTERRUPT flag set. -arca
  25.214 +	 */
  25.215 +	
  25.216 +	/* read Pentium cycle counter */
  25.217 +
  25.218 +	rdtsc(last_tsc_low, last_tsc_high);
  25.219 +
  25.220 +#if 0
  25.221 +	spin_lock(&i8253_lock);
  25.222 +	outb_p(0x00, PIT_MODE);     /* latch the count ASAP */
  25.223 +
  25.224 +	count = inb_p(PIT_CH0);    /* read the latched count */
  25.225 +	count |= inb(PIT_CH0) << 8;
  25.226 +
  25.227 +	/*
  25.228 +	 * VIA686a test code... reset the latch if count > max + 1
  25.229 +	 * from timer_pit.c - cjb
  25.230 +	 */
  25.231 +	if (count > LATCH) {
  25.232 +		outb_p(0x34, PIT_MODE);
  25.233 +		outb_p(LATCH & 0xff, PIT_CH0);
  25.234 +		outb(LATCH >> 8, PIT_CH0);
  25.235 +		count = LATCH - 1;
  25.236 +	}
  25.237 +
  25.238 +	spin_unlock(&i8253_lock);
  25.239 +
  25.240 +	if (pit_latch_buggy) {
  25.241 +		/* get center value of last 3 time lutch */
  25.242 +		if ((count2 >= count && count >= count1)
  25.243 +		    || (count1 >= count && count >= count2)) {
  25.244 +			count2 = count1; count1 = count;
  25.245 +		} else if ((count1 >= count2 && count2 >= count)
  25.246 +			   || (count >= count2 && count2 >= count1)) {
  25.247 +			countmp = count;count = count2;
  25.248 +			count2 = count1;count1 = countmp;
  25.249 +		} else {
  25.250 +			count2 = count1; count1 = count; count = count1;
  25.251 +		}
  25.252 +	}
  25.253 +#endif
  25.254 +
  25.255 +	/* lost tick compensation */
  25.256 +	delta = last_tsc_low - delta;
  25.257 +	{
  25.258 +		register unsigned long eax, edx;
  25.259 +		eax = delta;
  25.260 +		__asm__("mull %2"
  25.261 +		:"=a" (eax), "=d" (edx)
  25.262 +		:"rm" (fast_gettimeoffset_quotient),
  25.263 +		 "0" (eax));
  25.264 +		delta = edx;
  25.265 +	}
  25.266 +	delta += delay_at_last_interrupt;
  25.267 +	lost = delta/(1000000/HZ);
  25.268 +	delay = delta%(1000000/HZ);
  25.269 +	if (lost >= 2) {
  25.270 +		jiffies_64 += lost-1;
  25.271 +
  25.272 +		/* sanity check to ensure we're not always losing ticks */
  25.273 +		if (lost_count++ > 100) {
  25.274 +			printk(KERN_WARNING "Losing too many ticks!\n");
  25.275 +			printk(KERN_WARNING "TSC cannot be used as a timesource.  \n");
  25.276 +			printk(KERN_WARNING "Possible reasons for this are:\n");
  25.277 +			printk(KERN_WARNING "  You're running with Speedstep,\n");
  25.278 +			printk(KERN_WARNING "  You don't have DMA enabled for your hard disk (see hdparm),\n");
  25.279 +			printk(KERN_WARNING "  Incorrect TSC synchronization on an SMP system (see dmesg).\n");
  25.280 +			printk(KERN_WARNING "Falling back to a sane timesource now.\n");
  25.281 +
  25.282 +			clock_fallback();
  25.283 +		}
  25.284 +		/* ... but give the TSC a fair chance */
  25.285 +		if (lost_count > 25)
  25.286 +			cpufreq_delayed_get();
  25.287 +	} else
  25.288 +		lost_count = 0;
  25.289 +	/* update the monotonic base value */
  25.290 +	this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
  25.291 +	monotonic_base += cycles_2_ns(this_offset - last_offset);
  25.292 +	write_sequnlock(&monotonic_lock);
  25.293 +
  25.294 +#if 0
  25.295 +	/* calculate delay_at_last_interrupt */
  25.296 +	count = ((LATCH-1) - count) * TICK_SIZE;
  25.297 +	delay_at_last_interrupt = (count + LATCH/2) / LATCH;
  25.298 +#else
  25.299 +	delay_at_last_interrupt = 0;
  25.300 +#endif
  25.301 +
  25.302 +	/* catch corner case where tick rollover occured 
  25.303 +	 * between tsc and pit reads (as noted when 
  25.304 +	 * usec delta is > 90% # of usecs/tick)
  25.305 +	 */
  25.306 +	if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ))
  25.307 +		jiffies_64++;
  25.308 +}
  25.309 +
  25.310 +static void delay_tsc(unsigned long loops)
  25.311 +{
  25.312 +	unsigned long bclock, now;
  25.313 +	
  25.314 +	rdtscl(bclock);
  25.315 +	do
  25.316 +	{
  25.317 +		rep_nop();
  25.318 +		rdtscl(now);
  25.319 +	} while ((now-bclock) < loops);
  25.320 +}
  25.321 +
  25.322 +#ifdef CONFIG_HPET_TIMER
  25.323 +static void mark_offset_tsc_hpet(void)
  25.324 +{
  25.325 +	unsigned long long this_offset, last_offset;
  25.326 + 	unsigned long offset, temp, hpet_current;
  25.327 +
  25.328 +	write_seqlock(&monotonic_lock);
  25.329 +	last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
  25.330 +	/*
  25.331 +	 * It is important that these two operations happen almost at
  25.332 +	 * the same time. We do the RDTSC stuff first, since it's
  25.333 +	 * faster. To avoid any inconsistencies, we need interrupts
  25.334 +	 * disabled locally.
  25.335 +	 */
  25.336 +	/*
  25.337 +	 * Interrupts are just disabled locally since the timer irq
  25.338 +	 * has the SA_INTERRUPT flag set. -arca
  25.339 +	 */
  25.340 +	/* read Pentium cycle counter */
  25.341 +
  25.342 +	hpet_current = hpet_readl(HPET_COUNTER);
  25.343 +	rdtsc(last_tsc_low, last_tsc_high);
  25.344 +
  25.345 +	/* lost tick compensation */
  25.346 +	offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
  25.347 +	if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) {
  25.348 +		int lost_ticks = (offset - hpet_last) / hpet_tick;
  25.349 +		jiffies_64 += lost_ticks;
  25.350 +	}
  25.351 +	hpet_last = hpet_current;
  25.352 +
  25.353 +	/* update the monotonic base value */
  25.354 +	this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
  25.355 +	monotonic_base += cycles_2_ns(this_offset - last_offset);
  25.356 +	write_sequnlock(&monotonic_lock);
  25.357 +
  25.358 +	/* calculate delay_at_last_interrupt */
  25.359 +	/*
  25.360 +	 * Time offset = (hpet delta) * ( usecs per HPET clock )
  25.361 +	 *             = (hpet delta) * ( usecs per tick / HPET clocks per tick)
  25.362 +	 *             = (hpet delta) * ( hpet_usec_quotient ) / (2^32)
  25.363 +	 * Where,
  25.364 +	 * hpet_usec_quotient = (2^32 * usecs per tick)/HPET clocks per tick
  25.365 +	 */
  25.366 +	delay_at_last_interrupt = hpet_current - offset;
  25.367 +	ASM_MUL64_REG(temp, delay_at_last_interrupt,
  25.368 +			hpet_usec_quotient, delay_at_last_interrupt);
  25.369 +}
  25.370 +#endif
  25.371 +
  25.372 +
  25.373 +#ifdef CONFIG_CPU_FREQ
  25.374 +#include <linux/workqueue.h>
  25.375 +
  25.376 +static unsigned int cpufreq_delayed_issched = 0;
  25.377 +static unsigned int cpufreq_init = 0;
  25.378 +static struct work_struct cpufreq_delayed_get_work;
  25.379 +
  25.380 +static void handle_cpufreq_delayed_get(void *v)
  25.381 +{
  25.382 +	unsigned int cpu;
  25.383 +	for_each_online_cpu(cpu) {
  25.384 +		cpufreq_get(cpu);
  25.385 +	}
  25.386 +	cpufreq_delayed_issched = 0;
  25.387 +}
  25.388 +
  25.389 +/* if we notice lost ticks, schedule a call to cpufreq_get() as it tries
  25.390 + * to verify the CPU frequency the timing core thinks the CPU is running
  25.391 + * at is still correct.
  25.392 + */
  25.393 +static inline void cpufreq_delayed_get(void) 
  25.394 +{
  25.395 +	if (cpufreq_init && !cpufreq_delayed_issched) {
  25.396 +		cpufreq_delayed_issched = 1;
  25.397 +		printk(KERN_DEBUG "Losing some ticks... checking if CPU frequency changed.\n");
  25.398 +		schedule_work(&cpufreq_delayed_get_work);
  25.399 +	}
  25.400 +}
  25.401 +
  25.402 +/* If the CPU frequency is scaled, TSC-based delays will need a different
  25.403 + * loops_per_jiffy value to function properly.
  25.404 + */
  25.405 +
  25.406 +static unsigned int  ref_freq = 0;
  25.407 +static unsigned long loops_per_jiffy_ref = 0;
  25.408 +
  25.409 +#ifndef CONFIG_SMP
  25.410 +static unsigned long fast_gettimeoffset_ref = 0;
  25.411 +static unsigned long cpu_khz_ref = 0;
  25.412 +#endif
  25.413 +
  25.414 +static int
  25.415 +time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
  25.416 +		       void *data)
  25.417 +{
  25.418 +	struct cpufreq_freqs *freq = data;
  25.419 +
  25.420 +	write_seqlock_irq(&xtime_lock);
  25.421 +	if (!ref_freq) {
  25.422 +		ref_freq = freq->old;
  25.423 +		loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
  25.424 +#ifndef CONFIG_SMP
  25.425 +		fast_gettimeoffset_ref = fast_gettimeoffset_quotient;
  25.426 +		cpu_khz_ref = cpu_khz;
  25.427 +#endif
  25.428 +	}
  25.429 +
  25.430 +	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
  25.431 +	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
  25.432 +	    (val == CPUFREQ_RESUMECHANGE)) {
  25.433 +		if (!(freq->flags & CPUFREQ_CONST_LOOPS))
  25.434 +			cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
  25.435 +#ifndef CONFIG_SMP
  25.436 +		if (cpu_khz)
  25.437 +			cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
  25.438 +		if (use_tsc) {
  25.439 +			if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
  25.440 +				fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
  25.441 +				set_cyc2ns_scale(cpu_khz/1000);
  25.442 +			}
  25.443 +		}
  25.444 +#endif
  25.445 +	}
  25.446 +	write_sequnlock_irq(&xtime_lock);
  25.447 +
  25.448 +	return 0;
  25.449 +}
  25.450 +
  25.451 +static struct notifier_block time_cpufreq_notifier_block = {
  25.452 +	.notifier_call	= time_cpufreq_notifier
  25.453 +};
  25.454 +
  25.455 +
  25.456 +static int __init cpufreq_tsc(void)
  25.457 +{
  25.458 +	int ret;
  25.459 +	INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL);
  25.460 +	ret = cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
  25.461 +	if (!ret)
  25.462 +		cpufreq_init = 1;
  25.463 +	return ret;
  25.464 +}
  25.465 +core_initcall(cpufreq_tsc);
  25.466 +
  25.467 +#else /* CONFIG_CPU_FREQ */
  25.468 +static inline void cpufreq_delayed_get(void) { return; }
  25.469 +#endif 
  25.470 +
  25.471 +
  25.472 +static int __init init_tsc(char* override)
  25.473 +{
  25.474 +	unsigned long long alarm;
  25.475 +	u64 __cpu_khz;
  25.476 +
  25.477 +	__cpu_khz = HYPERVISOR_shared_info->cpu_freq;
  25.478 +	do_div(__cpu_khz, 1000);
  25.479 +	cpu_khz = (u32)__cpu_khz;
  25.480 +	printk(KERN_INFO "Xen reported: %lu.%03lu MHz processor.\n", 
  25.481 +	       cpu_khz / 1000, cpu_khz % 1000);
  25.482 +
  25.483 +	/* (10^6 * 2^32) / cpu_khz = (2^32 * 1 / (clocks/us)) */
  25.484 +	{	
  25.485 +		unsigned long eax=0, edx=1000;
  25.486 +		__asm__("divl %2"
  25.487 +		    :"=a" (fast_gettimeoffset_quotient), "=d" (edx)
  25.488 +		    :"r" (cpu_khz),
  25.489 +		    "0" (eax), "1" (edx));
  25.490 +	}
  25.491 +
  25.492 +	set_cyc2ns_scale(cpu_khz/1000);
  25.493 +
  25.494 +	__get_time_values_from_xen();
  25.495 +
  25.496 +	rdtscll(alarm);
  25.497 +
  25.498 +	return 0;
  25.499 +}
  25.500 +
  25.501 +#ifndef CONFIG_X86_TSC
  25.502 +/* disable flag for tsc.  Takes effect by clearing the TSC cpu flag
  25.503 + * in cpu/common.c */
  25.504 +static int __init tsc_setup(char *str)
  25.505 +{
  25.506 +	tsc_disable = 1;
  25.507 +	return 1;
  25.508 +}
  25.509 +#else
  25.510 +static int __init tsc_setup(char *str)
  25.511 +{
  25.512 +	printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
  25.513 +				"cannot disable TSC.\n");
  25.514 +	return 1;
  25.515 +}
  25.516 +#endif
  25.517 +__setup("notsc", tsc_setup);
  25.518 +
  25.519 +
  25.520 +
  25.521 +/************************************************************/
  25.522 +
  25.523 +/* tsc timer_opts struct */
  25.524 +struct timer_opts timer_tsc = {
  25.525 +	.name = 	"tsc",
  25.526 +	.init =		init_tsc,
  25.527 +	.mark_offset =	mark_offset_tsc, 
  25.528 +	.get_offset =	get_offset_tsc,
  25.529 +	.monotonic_clock =	monotonic_clock_tsc,
  25.530 +	.delay = delay_tsc,
  25.531 +};
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c	Wed Jul 14 16:41:41 2004 +0000
    26.3 @@ -0,0 +1,1040 @@
    26.4 +/*
    26.5 + *  linux/arch/i386/traps.c
    26.6 + *
    26.7 + *  Copyright (C) 1991, 1992  Linus Torvalds
    26.8 + *
    26.9 + *  Pentium III FXSR, SSE support
   26.10 + *	Gareth Hughes <gareth@valinux.com>, May 2000
   26.11 + */
   26.12 +
   26.13 +/*
   26.14 + * 'Traps.c' handles hardware traps and faults after we have saved some
   26.15 + * state in 'asm.s'.
   26.16 + */
   26.17 +#include <linux/config.h>
   26.18 +#include <linux/sched.h>
   26.19 +#include <linux/kernel.h>
   26.20 +#include <linux/string.h>
   26.21 +#include <linux/errno.h>
   26.22 +#include <linux/timer.h>
   26.23 +#include <linux/mm.h>
   26.24 +#include <linux/init.h>
   26.25 +#include <linux/delay.h>
   26.26 +#include <linux/spinlock.h>
   26.27 +#include <linux/interrupt.h>
   26.28 +#include <linux/highmem.h>
   26.29 +#include <linux/kallsyms.h>
   26.30 +#include <linux/ptrace.h>
   26.31 +#include <linux/version.h>
   26.32 +
   26.33 +#ifdef CONFIG_EISA
   26.34 +#include <linux/ioport.h>
   26.35 +#include <linux/eisa.h>
   26.36 +#endif
   26.37 +
   26.38 +#ifdef CONFIG_MCA
   26.39 +#include <linux/mca.h>
   26.40 +#endif
   26.41 +
   26.42 +#include <asm/processor.h>
   26.43 +#include <asm/system.h>
   26.44 +#include <asm/uaccess.h>
   26.45 +#include <asm/io.h>
   26.46 +#include <asm/atomic.h>
   26.47 +#include <asm/debugreg.h>
   26.48 +#include <asm/desc.h>
   26.49 +#include <asm/i387.h>
   26.50 +#include <asm/nmi.h>
   26.51 +
   26.52 +#include <asm/smp.h>
   26.53 +#include <asm/pgalloc.h>
   26.54 +#include <asm/arch_hooks.h>
   26.55 +
   26.56 +#include <linux/irq.h>
   26.57 +#include <linux/module.h>
   26.58 +
   26.59 +#include "mach_traps.h"
   26.60 +
   26.61 +asmlinkage int system_call(void);
   26.62 +asmlinkage void lcall7(void);
   26.63 +asmlinkage void lcall27(void);
   26.64 +
   26.65 +asmlinkage void safe_page_fault(void);
   26.66 +
   26.67 +/* Do we ignore FPU interrupts ? */
   26.68 +char ignore_fpu_irq = 0;
   26.69 +
   26.70 +/*
   26.71 + * The IDT has to be page-aligned to simplify the Pentium
   26.72 + * F0 0F bug workaround.. We have a special link segment
   26.73 + * for this.
   26.74 + */
   26.75 +struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
   26.76 +
   26.77 +asmlinkage void divide_error(void);
   26.78 +asmlinkage void debug(void);
   26.79 +asmlinkage void nmi(void);
   26.80 +asmlinkage void int3(void);
   26.81 +asmlinkage void overflow(void);
   26.82 +asmlinkage void bounds(void);
   26.83 +asmlinkage void invalid_op(void);
   26.84 +asmlinkage void device_not_available(void);
   26.85 +asmlinkage void double_fault(void);
   26.86 +asmlinkage void coprocessor_segment_overrun(void);
   26.87 +asmlinkage void invalid_TSS(void);
   26.88 +asmlinkage void segment_not_present(void);
   26.89 +asmlinkage void stack_segment(void);
   26.90 +asmlinkage void general_protection(void);
   26.91 +asmlinkage void page_fault(void);
   26.92 +asmlinkage void coprocessor_error(void);
   26.93 +asmlinkage void simd_coprocessor_error(void);
   26.94 +asmlinkage void alignment_check(void);
   26.95 +asmlinkage void spurious_interrupt_bug(void);
   26.96 +asmlinkage void machine_check(void);
   26.97 +
   26.98 +static int kstack_depth_to_print = 24;
   26.99 +
  26.100 +static int valid_stack_ptr(struct task_struct *task, void *p)
  26.101 +{
  26.102 +	if (p <= (void *)task->thread_info)
  26.103 +		return 0;
  26.104 +	if (kstack_end(p))
  26.105 +		return 0;
  26.106 +	return 1;
  26.107 +}
  26.108 +
  26.109 +#ifdef CONFIG_FRAME_POINTER
  26.110 +void print_context_stack(struct task_struct *task, unsigned long *stack,
  26.111 +			 unsigned long ebp)
  26.112 +{
  26.113 +	unsigned long addr;
  26.114 +
  26.115 +	while (valid_stack_ptr(task, (void *)ebp)) {
  26.116 +		addr = *(unsigned long *)(ebp + 4);
  26.117 +		printk(" [<%08lx>] ", addr);
  26.118 +		print_symbol("%s", addr);
  26.119 +		printk("\n");
  26.120 +		ebp = *(unsigned long *)ebp;
  26.121 +	}
  26.122 +}
  26.123 +#else
  26.124 +void print_context_stack(struct task_struct *task, unsigned long *stack,
  26.125 +			 unsigned long ebp)
  26.126 +{
  26.127 +	unsigned long addr;
  26.128 +
  26.129 +	while (!kstack_end(stack)) {
  26.130 +		addr = *stack++;
  26.131 +		if (kernel_text_address(addr)) {
  26.132 +			printk(" %p: [<%08lx>] ", stack - 4, addr);
  26.133 +			print_symbol("%s\n", addr);
  26.134 +		}
  26.135 +	}
  26.136 +}
  26.137 +#endif
  26.138 +
  26.139 +void show_trace(struct task_struct *task, unsigned long * stack)
  26.140 +{
  26.141 +	unsigned long ebp;
  26.142 +
  26.143 +	if (!task)
  26.144 +		task = current;
  26.145 +
  26.146 +	if (!valid_stack_ptr(task, stack)) {
  26.147 +		printk("Stack pointer is garbage, not printing trace\n");
  26.148 +		return;
  26.149 +	}
  26.150 +
  26.151 +	if (task == current) {
  26.152 +		/* Grab ebp right from our regs */
  26.153 +		asm ("movl %%ebp, %0" : "=r" (ebp) : );
  26.154 +	} else {
  26.155 +		/* ebp is the last reg pushed by switch_to */
  26.156 +		ebp = *(unsigned long *) task->thread.esp;
  26.157 +	}
  26.158 +
  26.159 +	while (1) {
  26.160 +		struct thread_info *context;
  26.161 +		context = (struct thread_info *)
  26.162 +			((unsigned long)stack & (~(THREAD_SIZE - 1)));
  26.163 +		print_context_stack(task, stack, ebp);
  26.164 +		stack = (unsigned long*)context->previous_esp;
  26.165 +		if (!stack)
  26.166 +			break;
  26.167 +		printk(" =======================\n");
  26.168 +	}
  26.169 +	printk("\n");
  26.170 +}
  26.171 +
  26.172 +void show_stack(struct task_struct *task, unsigned long *esp)
  26.173 +{
  26.174 +	unsigned long *stack;
  26.175 +	int i;
  26.176 +
  26.177 +	if (esp == NULL) {
  26.178 +		if (task)
  26.179 +			esp = (unsigned long*)task->thread.esp;
  26.180 +		else
  26.181 +			esp = (unsigned long *)&esp;
  26.182 +	}
  26.183 +
  26.184 +	stack = esp;
  26.185 +	for(i = 0; i < kstack_depth_to_print; i++) {
  26.186 +		if (kstack_end(stack))
  26.187 +			break;
  26.188 +		if (i && ((i % 8) == 0))
  26.189 +			printk("\n       ");
  26.190 +		printk("%08lx ", *stack++);
  26.191 +	}
  26.192 +	printk("\nCall Trace:\n");
  26.193 +	show_trace(task, esp);
  26.194 +}
  26.195 +
  26.196 +/*
  26.197 + * The architecture-independent dump_stack generator
  26.198 + */
  26.199 +void dump_stack(void)
  26.200 +{
  26.201 +	unsigned long stack;
  26.202 +
  26.203 +	show_trace(current, &stack);
  26.204 +}
  26.205 +
  26.206 +EXPORT_SYMBOL(dump_stack);
  26.207 +
  26.208 +void show_registers(struct pt_regs *regs)
  26.209 +{
  26.210 +	int i;
  26.211 +	int in_kernel = 1;
  26.212 +	unsigned long esp;
  26.213 +	unsigned short ss;
  26.214 +
  26.215 +	esp = (unsigned long) (&regs->esp);
  26.216 +	ss = __KERNEL_DS;
  26.217 +	if (regs->xcs & 2) {
  26.218 +		in_kernel = 0;
  26.219 +		esp = regs->esp;
  26.220 +		ss = regs->xss & 0xffff;
  26.221 +	}
  26.222 +	print_modules();
  26.223 +	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx"
  26.224 +			"   (%s) \n",
  26.225 +		smp_processor_id(), 0xffff & regs->xcs, regs->eip,
  26.226 +		print_tainted(), regs->eflags, UTS_RELEASE);
  26.227 +	print_symbol("EIP is at %s\n", regs->eip);
  26.228 +	printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
  26.229 +		regs->eax, regs->ebx, regs->ecx, regs->edx);
  26.230 +	printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
  26.231 +		regs->esi, regs->edi, regs->ebp, esp);
  26.232 +	printk("ds: %04x   es: %04x   ss: %04x\n",
  26.233 +		regs->xds & 0xffff, regs->xes & 0xffff, ss);
  26.234 +	printk("Process %s (pid: %d, threadinfo=%p task=%p)",
  26.235 +		current->comm, current->pid, current_thread_info(), current);
  26.236 +	/*
  26.237 +	 * When in-kernel, we also print out the stack and code at the
  26.238 +	 * time of the fault..
  26.239 +	 */
  26.240 +	if (in_kernel) {
  26.241 +
  26.242 +		printk("\nStack: ");
  26.243 +		show_stack(NULL, (unsigned long*)esp);
  26.244 +
  26.245 +		printk("Code: ");
  26.246 +		if(regs->eip < PAGE_OFFSET)
  26.247 +			goto bad;
  26.248 +
  26.249 +		for(i=0;i<20;i++)
  26.250 +		{
  26.251 +			unsigned char c;
  26.252 +			if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
  26.253 +bad:
  26.254 +				printk(" Bad EIP value.");
  26.255 +				break;
  26.256 +			}
  26.257 +			printk("%02x ", c);
  26.258 +		}
  26.259 +	}
  26.260 +	printk("\n");
  26.261 +}	
  26.262 +
  26.263 +static void handle_BUG(struct pt_regs *regs)
  26.264 +{
  26.265 +	unsigned short ud2;
  26.266 +	unsigned short line;
  26.267 +	char *file;
  26.268 +	char c;
  26.269 +	unsigned long eip;
  26.270 +
  26.271 +	if (regs->xcs & 2)
  26.272 +		goto no_bug;		/* Not in kernel */
  26.273 +
  26.274 +	eip = regs->eip;
  26.275 +
  26.276 +	if (eip < PAGE_OFFSET)
  26.277 +		goto no_bug;
  26.278 +	if (__get_user(ud2, (unsigned short *)eip))
  26.279 +		goto no_bug;
  26.280 +	if (ud2 != 0x0b0f)
  26.281 +		goto no_bug;
  26.282 +	if (__get_user(line, (unsigned short *)(eip + 2)))
  26.283 +		goto bug;
  26.284 +	if (__get_user(file, (char **)(eip + 4)) ||
  26.285 +		(unsigned long)file < PAGE_OFFSET || __get_user(c, file))
  26.286 +		file = "<bad filename>";
  26.287 +
  26.288 +	printk("------------[ cut here ]------------\n");
  26.289 +	printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line);
  26.290 +
  26.291 +no_bug:
  26.292 +	return;
  26.293 +
  26.294 +	/* Here we know it was a BUG but file-n-line is unavailable */
  26.295 +bug:
  26.296 +	printk("Kernel BUG\n");
  26.297 +}
  26.298 +
  26.299 +spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
  26.300 +
  26.301 +void die(const char * str, struct pt_regs * regs, long err)
  26.302 +{
  26.303 +	static int die_counter;
  26.304 +	int nl = 0;
  26.305 +
  26.306 +	console_verbose();
  26.307 +	spin_lock_irq(&die_lock);
  26.308 +	bust_spinlocks(1);
  26.309 +	handle_BUG(regs);
  26.310 +	printk(KERN_ALERT "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
  26.311 +#ifdef CONFIG_PREEMPT
  26.312 +	printk("PREEMPT ");
  26.313 +	nl = 1;
  26.314 +#endif
  26.315 +#ifdef CONFIG_SMP
  26.316 +	printk("SMP ");
  26.317 +	nl = 1;
  26.318 +#endif
  26.319 +#ifdef CONFIG_DEBUG_PAGEALLOC
  26.320 +	printk("DEBUG_PAGEALLOC");
  26.321 +	nl = 1;
  26.322 +#endif
  26.323 +	if (nl)
  26.324 +		printk("\n");
  26.325 +	show_registers(regs);
  26.326 +	bust_spinlocks(0);
  26.327 +	spin_unlock_irq(&die_lock);
  26.328 +	if (in_interrupt())
  26.329 +		panic("Fatal exception in interrupt");
  26.330 +
  26.331 +	if (panic_on_oops) {
  26.332 +		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
  26.333 +		set_current_state(TASK_UNINTERRUPTIBLE);
  26.334 +		schedule_timeout(5 * HZ);
  26.335 +		panic("Fatal exception");
  26.336 +	}
  26.337 +	do_exit(SIGSEGV);
  26.338 +}
  26.339 +
  26.340 +static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
  26.341 +{
  26.342 +	if (!(regs->eflags & VM_MASK) && !(2 & regs->xcs))
  26.343 +		die(str, regs, err);
  26.344 +}
  26.345 +
  26.346 +static inline unsigned long get_cr2(void)
  26.347 +{
  26.348 +	unsigned long address;
  26.349 +
  26.350 +	/* get the address */
  26.351 +	__asm__("movl %%cr2,%0":"=r" (address));
  26.352 +	return address;
  26.353 +}
  26.354 +
  26.355 +static inline void do_trap(int trapnr, int signr, char *str, int vm86,
  26.356 +			   struct pt_regs * regs, long error_code, siginfo_t *info)
  26.357 +{
  26.358 +	if (regs->eflags & VM_MASK) {
  26.359 +		if (vm86)
  26.360 +			goto vm86_trap;
  26.361 +		goto trap_signal;
  26.362 +	}
  26.363 +
  26.364 +	if (!(regs->xcs & 2))
  26.365 +		goto kernel_trap;
  26.366 +
  26.367 +	trap_signal: {
  26.368 +		struct task_struct *tsk = current;
  26.369 +		tsk->thread.error_code = error_code;
  26.370 +		tsk->thread.trap_no = trapnr;
  26.371 +		if (info)
  26.372 +			force_sig_info(signr, info, tsk);
  26.373 +		else
  26.374 +			force_sig(signr, tsk);
  26.375 +		return;
  26.376 +	}
  26.377 +
  26.378 +	kernel_trap: {
  26.379 +		if (!fixup_exception(regs))
  26.380 +			die(str, regs, error_code);
  26.381 +		return;
  26.382 +	}
  26.383 +
  26.384 +	vm86_trap: {
  26.385 +		int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr);
  26.386 +		if (ret) goto trap_signal;
  26.387 +		return;
  26.388 +	}
  26.389 +}
  26.390 +
  26.391 +#define DO_ERROR(trapnr, signr, str, name) \
  26.392 +asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
  26.393 +{ \
  26.394 +	do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
  26.395 +}
  26.396 +
  26.397 +#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
  26.398 +asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
  26.399 +{ \
  26.400 +	siginfo_t info; \
  26.401 +	info.si_signo = signr; \
  26.402 +	info.si_errno = 0; \
  26.403 +	info.si_code = sicode; \
  26.404 +	info.si_addr = (void *)siaddr; \
  26.405 +	do_trap(trapnr, signr, str, 0, regs, error_code, &info); \
  26.406 +}
  26.407 +
  26.408 +#define DO_VM86_ERROR(trapnr, signr, str, name) \
  26.409 +asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
  26.410 +{ \
  26.411 +	do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
  26.412 +}
  26.413 +
  26.414 +#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
  26.415 +asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
  26.416 +{ \
  26.417 +	siginfo_t info; \
  26.418 +	info.si_signo = signr; \
  26.419 +	info.si_errno = 0; \
  26.420 +	info.si_code = sicode; \
  26.421 +	info.si_addr = (void *)siaddr; \
  26.422 +	do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
  26.423 +}
  26.424 +
  26.425 +DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->eip)
  26.426 +DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
  26.427 +DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
  26.428 +DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
  26.429 +DO_ERROR_INFO( 6, SIGILL,  "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
  26.430 +DO_VM86_ERROR( 7, SIGSEGV, "device not available", device_not_available)
  26.431 +DO_ERROR( 8, SIGSEGV, "double fault", double_fault)
  26.432 +DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
  26.433 +DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
  26.434 +DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
  26.435 +DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
  26.436 +DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
  26.437 +#ifdef CONFIG_X86_MCE
  26.438 +DO_ERROR(18, SIGBUS, "machine check", machine_check)
  26.439 +#endif
  26.440 +
  26.441 +asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
  26.442 +{
  26.443 +	/*
  26.444 +	 * If we trapped on an LDT access then ensure that the default_ldt is
  26.445 +	 * loaded, if nothing else. We load default_ldt lazily because LDT
  26.446 +	 * switching costs time and many applications don't need it.
  26.447 +	 */
  26.448 +	if (unlikely((error_code & 6) == 4)) {
  26.449 +		unsigned long ldt;
  26.450 +		__asm__ __volatile__ ("sldt %0" : "=r" (ldt));
  26.451 +		if (ldt == 0) {
  26.452 +			mmu_update_t u;
  26.453 +			u.ptr = MMU_EXTENDED_COMMAND;
  26.454 +			u.ptr |= (unsigned long)&default_ldt[0];
  26.455 +			u.val = MMUEXT_SET_LDT | (5 << MMUEXT_CMD_SHIFT);
  26.456 +			if (unlikely(HYPERVISOR_mmu_update(&u, 1, NULL) < 0)) {
  26.457 +				show_trace(NULL, (unsigned long *)&u);
  26.458 +				panic("Failed to install default LDT");
  26.459 +			}
  26.460 +			return;
  26.461 +		}
  26.462 +	}
  26.463 +
  26.464 +#if 0
  26.465 +	if (regs->eflags & X86_EFLAGS_IF)
  26.466 +		local_irq_enable();
  26.467 +#endif
  26.468 + 
  26.469 +	if (regs->eflags & VM_MASK)
  26.470 +		goto gp_in_vm86;
  26.471 +
  26.472 +	if (!(regs->xcs & 2))
  26.473 +		goto gp_in_kernel;
  26.474 +
  26.475 +	current->thread.error_code = error_code;
  26.476 +	current->thread.trap_no = 13;
  26.477 +	force_sig(SIGSEGV, current);
  26.478 +	return;
  26.479 +
  26.480 +gp_in_vm86:
  26.481 +	local_irq_enable();
  26.482 +	handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
  26.483 +	return;
  26.484 +
  26.485 +gp_in_kernel:
  26.486 +	if (!fixup_exception(regs))
  26.487 +		die("general protection fault", regs, error_code);
  26.488 +}
  26.489 +
  26.490 +static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
  26.491 +{
  26.492 +	printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
  26.493 +	printk("You probably have a hardware problem with your RAM chips\n");
  26.494 +
  26.495 +	/* Clear and disable the memory parity error line. */
  26.496 +	clear_mem_error(reason);
  26.497 +}
  26.498 +
  26.499 +static void io_check_error(unsigned char reason, struct pt_regs * regs)
  26.500 +{
  26.501 +	unsigned long i;
  26.502 +
  26.503 +	printk("NMI: IOCK error (debug interrupt?)\n");
  26.504 +	show_registers(regs);
  26.505 +
  26.506 +	/* Re-enable the IOCK line, wait for a few seconds */
  26.507 +	reason = (reason & 0xf) | 8;
  26.508 +	outb(reason, 0x61);
  26.509 +	i = 2000;
  26.510 +	while (--i) udelay(1000);
  26.511 +	reason &= ~8;
  26.512 +	outb(reason, 0x61);
  26.513 +}
  26.514 +
  26.515 +static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
  26.516 +{
  26.517 +#ifdef CONFIG_MCA
  26.518 +	/* Might actually be able to figure out what the guilty party
  26.519 +	* is. */
  26.520 +	if( MCA_bus ) {
  26.521 +		mca_handle_nmi();
  26.522 +		return;
  26.523 +	}
  26.524 +#endif
  26.525 +	printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
  26.526 +		reason, smp_processor_id());
  26.527 +	printk("Dazed and confused, but trying to continue\n");
  26.528 +	printk("Do you have a strange power saving mode enabled?\n");
  26.529 +}
  26.530 +
  26.531 +static void default_do_nmi(struct pt_regs * regs)
  26.532 +{
  26.533 +	unsigned char reason = get_nmi_reason();
  26.534 + 
  26.535 +	if (!(reason & 0xc0)) {
  26.536 +#ifdef CONFIG_X86_LOCAL_APIC
  26.537 +		/*
  26.538 +		 * Ok, so this is none of the documented NMI sources,
  26.539 +		 * so it must be the NMI watchdog.
  26.540 +		 */
  26.541 +		if (nmi_watchdog) {
  26.542 +			nmi_watchdog_tick(regs);
  26.543 +			return;
  26.544 +		}
  26.545 +#endif
  26.546 +		unknown_nmi_error(reason, regs);
  26.547 +		return;
  26.548 +	}
  26.549 +	if (reason & 0x80)
  26.550 +		mem_parity_error(reason, regs);
  26.551 +	if (reason & 0x40)
  26.552 +		io_check_error(reason, regs);
  26.553 +	/*
  26.554 +	 * Reassert NMI in case it became active meanwhile
  26.555 +	 * as it's edge-triggered.
  26.556 +	 */
  26.557 +	reassert_nmi();
  26.558 +}
  26.559 +
  26.560 +static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
  26.561 +{
  26.562 +	return 0;
  26.563 +}
  26.564 + 
  26.565 +static nmi_callback_t nmi_callback = dummy_nmi_callback;
  26.566 + 
  26.567 +asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
  26.568 +{
  26.569 +	int cpu;
  26.570 +
  26.571 +	nmi_enter();
  26.572 +
  26.573 +	cpu = smp_processor_id();
  26.574 +	++nmi_count(cpu);
  26.575 +
  26.576 +	if (!nmi_callback(regs, cpu))
  26.577 +		default_do_nmi(regs);
  26.578 +
  26.579 +	nmi_exit();
  26.580 +}
  26.581 +
  26.582 +void set_nmi_callback(nmi_callback_t callback)
  26.583 +{
  26.584 +	nmi_callback = callback;
  26.585 +}
  26.586 +
  26.587 +void unset_nmi_callback(void)
  26.588 +{
  26.589 +	nmi_callback = dummy_nmi_callback;
  26.590 +}
  26.591 +
  26.592 +/*
  26.593 + * Our handling of the processor debug registers is non-trivial.
  26.594 + * We do not clear them on entry and exit from the kernel. Therefore
  26.595 + * it is possible to get a watchpoint trap here from inside the kernel.
  26.596 + * However, the code in ./ptrace.c has ensured that the user can
  26.597 + * only set watchpoints on userspace addresses. Therefore the in-kernel
  26.598 + * watchpoint trap can only occur in code which is reading/writing
  26.599 + * from user space. Such code must not hold kernel locks (since it
  26.600 + * can equally take a page fault), therefore it is safe to call
  26.601 + * force_sig_info even though that claims and releases locks.
  26.602 + * 
  26.603 + * Code in ./signal.c ensures that the debug control register
  26.604 + * is restored before we deliver any signal, and therefore that
  26.605 + * user code runs with the correct debug control register even though
  26.606 + * we clear it here.
  26.607 + *
  26.608 + * Being careful here means that we don't have to be as careful in a
  26.609 + * lot of more complicated places (task switching can be a bit lazy
  26.610 + * about restoring all the debug state, and ptrace doesn't have to
  26.611 + * find every occurrence of the TF bit that could be saved away even
  26.612 + * by user code)
  26.613 + */
  26.614 +asmlinkage void do_debug(struct pt_regs * regs, long error_code)
  26.615 +{
  26.616 +	unsigned int condition;
  26.617 +	struct task_struct *tsk = current;
  26.618 +	siginfo_t info;
  26.619 +
  26.620 +	condition = HYPERVISOR_get_debugreg(6);
  26.621 +
  26.622 +#if 0
  26.623 +	/* It's safe to allow irq's after DR6 has been saved */
  26.624 +	if (regs->eflags & X86_EFLAGS_IF)
  26.625 +		local_irq_enable();
  26.626 +#endif
  26.627 +
  26.628 +	/* Mask out spurious debug traps due to lazy DR7 setting */
  26.629 +	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
  26.630 +		if (!tsk->thread.debugreg[7])
  26.631 +			goto clear_dr7;
  26.632 +	}
  26.633 +
  26.634 +	if (regs->eflags & VM_MASK)
  26.635 +		goto debug_vm86;
  26.636 +
  26.637 +	/* Save debug status register where ptrace can see it */
  26.638 +	tsk->thread.debugreg[6] = condition;
  26.639 +
  26.640 +	/* Mask out spurious TF errors due to lazy TF clearing */
  26.641 +	if (condition & DR_STEP) {
  26.642 +		/*
  26.643 +		 * The TF error should be masked out only if the current
  26.644 +		 * process is not traced and if the TRAP flag has been set
  26.645 +		 * previously by a tracing process (condition detected by
  26.646 +		 * the PT_DTRACE flag); remember that the i386 TRAP flag
  26.647 +		 * can be modified by the process itself in user mode,
  26.648 +		 * allowing programs to debug themselves without the ptrace()
  26.649 +		 * interface.
  26.650 +		 */
  26.651 +		if ((regs->xcs & 2) == 0)
  26.652 +			goto clear_TF_reenable;
  26.653 +		if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
  26.654 +			goto clear_TF;
  26.655 +	}
  26.656 +
  26.657 +	/* Ok, finally something we can handle */
  26.658 +	tsk->thread.trap_no = 1;
  26.659 +	tsk->thread.error_code = error_code;
  26.660 +	info.si_signo = SIGTRAP;
  26.661 +	info.si_errno = 0;
  26.662 +	info.si_code = TRAP_BRKPT;
  26.663 +	
  26.664 +	/* If this is a kernel mode trap, save the user PC on entry to 
  26.665 +	 * the kernel, that's what the debugger can make sense of.
  26.666 +	 */
  26.667 +	info.si_addr = ((regs->xcs & 2) == 0) ? (void *)tsk->thread.eip : 
  26.668 +	                                        (void *)regs->eip;
  26.669 +	force_sig_info(SIGTRAP, &info, tsk);
  26.670 +
  26.671 +	/* Disable additional traps. They'll be re-enabled when
  26.672 +	 * the signal is delivered.
  26.673 +	 */
  26.674 +clear_dr7:
  26.675 +	HYPERVISOR_set_debugreg(7, 0);
  26.676 +	return;
  26.677 +
  26.678 +debug_vm86:
  26.679 +	handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
  26.680 +	return;
  26.681 +
  26.682 +clear_TF_reenable:
  26.683 +	set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
  26.684 +clear_TF:
  26.685 +	regs->eflags &= ~TF_MASK;
  26.686 +	return;
  26.687 +}
  26.688 +
  26.689 +/*
  26.690 + * Note that we play around with the 'TS' bit in an attempt to get
  26.691 + * the correct behaviour even in the presence of the asynchronous
  26.692 + * IRQ13 behaviour
  26.693 + */
  26.694 +void math_error(void *eip)
  26.695 +{
  26.696 +	struct task_struct * task;
  26.697 +	siginfo_t info;
  26.698 +	unsigned short cwd, swd;
  26.699 +
  26.700 +	/*
  26.701 +	 * Save the info for the exception handler and clear the error.
  26.702 +	 */
  26.703 +	task = current;
  26.704 +	save_init_fpu(task);
  26.705 +	task->thread.trap_no = 16;
  26.706 +	task->thread.error_code = 0;
  26.707 +	info.si_signo = SIGFPE;
  26.708 +	info.si_errno = 0;
  26.709 +	info.si_code = __SI_FAULT;
  26.710 +	info.si_addr = eip;
  26.711 +	/*
  26.712 +	 * (~cwd & swd) will mask out exceptions that are not set to unmasked
  26.713 +	 * status.  0x3f is the exception bits in these regs, 0x200 is the
  26.714 +	 * C1 reg you need in case of a stack fault, 0x040 is the stack
  26.715 +	 * fault bit.  We should only be taking one exception at a time,
  26.716 +	 * so if this combination doesn't produce any single exception,
  26.717 +	 * then we have a bad program that isn't syncronizing its FPU usage
  26.718 +	 * and it will suffer the consequences since we won't be able to
  26.719 +	 * fully reproduce the context of the exception
  26.720 +	 */
  26.721 +	cwd = get_fpu_cwd(task);
  26.722 +	swd = get_fpu_swd(task);
  26.723 +	switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
  26.724 +		case 0x000:
  26.725 +		default:
  26.726 +			break;
  26.727 +		case 0x001: /* Invalid Op */
  26.728 +		case 0x040: /* Stack Fault XXX? */
  26.729 +		case 0x240: /* Stack Fault | Direction XXX? */
  26.730 +			info.si_code = FPE_FLTINV;
  26.731 +			/* Should we clear the SF or let user space do it ???? */
  26.732 +			break;
  26.733 +		case 0x002: /* Denormalize */
  26.734 +		case 0x010: /* Underflow */
  26.735 +			info.si_code = FPE_FLTUND;
  26.736 +			break;
  26.737 +		case 0x004: /* Zero Divide */
  26.738 +			info.si_code = FPE_FLTDIV;
  26.739 +			break;
  26.740 +		case 0x008: /* Overflow */
  26.741 +			info.si_code = FPE_FLTOVF;
  26.742 +			break;
  26.743 +		case 0x020: /* Precision */
  26.744 +			info.si_code = FPE_FLTRES;
  26.745 +			break;
  26.746 +	}
  26.747 +	force_sig_info(SIGFPE, &info, task);
  26.748 +}
  26.749 +
  26.750 +asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
  26.751 +{
  26.752 +	ignore_fpu_irq = 1;
  26.753 +	math_error((void *)regs->eip);
  26.754 +}
  26.755 +
  26.756 +void simd_math_error(void *eip)
  26.757 +{
  26.758 +	struct task_struct * task;
  26.759 +	siginfo_t info;
  26.760 +	unsigned short mxcsr;
  26.761 +
  26.762 +	/*
  26.763 +	 * Save the info for the exception handler and clear the error.
  26.764 +	 */
  26.765 +	task = current;
  26.766 +	save_init_fpu(task);
  26.767 +	task->thread.trap_no = 19;
  26.768 +	task->thread.error_code = 0;
  26.769 +	info.si_signo = SIGFPE;
  26.770 +	info.si_errno = 0;
  26.771 +	info.si_code = __SI_FAULT;
  26.772 +	info.si_addr = eip;
  26.773 +	/*
  26.774 +	 * The SIMD FPU exceptions are handled a little differently, as there
  26.775 +	 * is only a single status/control register.  Thus, to determine which
  26.776 +	 * unmasked exception was caught we must mask the exception mask bits
  26.777 +	 * at 0x1f80, and then use these to mask the exception bits at 0x3f.
  26.778 +	 */
  26.779 +	mxcsr = get_fpu_mxcsr(task);
  26.780 +	switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
  26.781 +		case 0x000:
  26.782 +		default:
  26.783 +			break;
  26.784 +		case 0x001: /* Invalid Op */