Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
Linus Torvalds [Mon, 28 Apr 2008 16:45:57 +0000 (09:45 -0700)]
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
  sparc: video drivers: add facility level
  sparc: tcx.c make tcx_init and tcx_exit static
  sparc: ffb.c make ffb_init and ffb_exit static
  sparc: cg14.c make cg14_init and cg15_exit static
  sparc: bw2.c fix bw2_exit
  sparc64: Fix accidental syscall restart on child return from clone/fork/vfork.
  sparc64: Clean up handling of pt_regs trap type encoding.
  sparc: Remove old style signal frame support.
  sparc64: Kill bogus RT_ALIGNEDSZ macro from signal.c
  sparc: sunzilog.c remove unused argument
  sparc: fix drivers/video/tcx.c warning
  sparc64: Kill unused local ISA bus layer.
  input: Rewrite sparcspkr device probing.
  sparc64: Do not ignore 'pmu' device ranges.
  sparc64: Kill ISA_FLOPPY_WORKS code.
  sparc64: Kill CONFIG_SPARC32_COMPAT
  sparc64: Cleanups and corrections for arch/sparc64/Kconfig
  sparc64: Fix wedged irq regression.

752 files changed:
Documentation/DocBook/kernel-api.tmpl
Documentation/fb/gxfb.txt [new file with mode: 0644]
Documentation/fb/intelfb.txt
Documentation/fb/lxfb.txt [new file with mode: 0644]
Documentation/fb/metronomefb.txt
Documentation/fb/modedb.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/Locking
Documentation/filesystems/tmpfs.txt
Documentation/filesystems/vfat.txt
Documentation/gpio.txt
Documentation/ia64/kvm.txt [new file with mode: 0644]
Documentation/ide/ide-tape.txt
Documentation/ide/ide.txt
Documentation/ioctl-number.txt
Documentation/kernel-parameters.txt
Documentation/kprobes.txt
Documentation/md.txt
Documentation/powerpc/booting-without-of.txt
Documentation/powerpc/kvm_440.txt [new file with mode: 0644]
Documentation/s390/kvm.txt [new file with mode: 0644]
Documentation/spi/spidev
Documentation/spi/spidev_fdx.c [new file with mode: 0644]
Documentation/vm/numa_memory_policy.txt
Kbuild
MAINTAINERS
arch/alpha/kernel/core_marvel.c
arch/alpha/kernel/core_t2.c
arch/alpha/kernel/core_titan.c
arch/alpha/kernel/core_tsunami.c
arch/alpha/kernel/module.c
arch/alpha/kernel/pci.c
arch/alpha/kernel/pci_iommu.c
arch/alpha/kernel/smp.c
arch/alpha/kernel/srm_env.c
arch/alpha/kernel/sys_alcor.c
arch/alpha/kernel/sys_marvel.c
arch/alpha/kernel/sys_sable.c
arch/alpha/kernel/sys_sio.c
arch/alpha/kernel/traps.c
arch/arm/mach-at91/at91sam9261_devices.c
arch/arm/mach-at91/at91sam9rl_devices.c
arch/avr32/kernel/setup.c
arch/cris/mm/init.c
arch/ia64/Kconfig
arch/ia64/Makefile
arch/ia64/kvm/Kconfig [new file with mode: 0644]
arch/ia64/kvm/Makefile [new file with mode: 0644]
arch/ia64/kvm/asm-offsets.c [new file with mode: 0644]
arch/ia64/kvm/kvm-ia64.c [new file with mode: 0644]
arch/ia64/kvm/kvm_fw.c [new file with mode: 0644]
arch/ia64/kvm/kvm_minstate.h [new file with mode: 0644]
arch/ia64/kvm/lapic.h [new file with mode: 0644]
arch/ia64/kvm/misc.h [new file with mode: 0644]
arch/ia64/kvm/mmio.c [new file with mode: 0644]
arch/ia64/kvm/optvfault.S [new file with mode: 0644]
arch/ia64/kvm/process.c [new file with mode: 0644]
arch/ia64/kvm/trampoline.S [new file with mode: 0644]
arch/ia64/kvm/vcpu.c [new file with mode: 0644]
arch/ia64/kvm/vcpu.h [new file with mode: 0644]
arch/ia64/kvm/vmm.c [new file with mode: 0644]
arch/ia64/kvm/vmm_ivt.S [new file with mode: 0644]
arch/ia64/kvm/vti.h [new file with mode: 0644]
arch/ia64/kvm/vtlb.c [new file with mode: 0644]
arch/ia64/mm/init.c
arch/m68k/kernel/ints.c
arch/m68k/mac/oss.c
arch/m68k/mm/init.c
arch/m68k/q40/q40ints.c
arch/mips/kernel/asm-offsets.c
arch/mips/vr41xx/common/init.c
arch/mips/vr41xx/common/siu.c
arch/parisc/mm/init.c
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/Makefile
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kvm/44x_tlb.c [new file with mode: 0644]
arch/powerpc/kvm/44x_tlb.h [new file with mode: 0644]
arch/powerpc/kvm/Kconfig [new file with mode: 0644]
arch/powerpc/kvm/Makefile [new file with mode: 0644]
arch/powerpc/kvm/booke_guest.c [new file with mode: 0644]
arch/powerpc/kvm/booke_host.c [new file with mode: 0644]
arch/powerpc/kvm/booke_interrupts.S [new file with mode: 0644]
arch/powerpc/kvm/emulate.c [new file with mode: 0644]
arch/powerpc/kvm/powerpc.c [new file with mode: 0644]
arch/powerpc/mm/mem.c
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/sysdev/axonram.c
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/fsl_soc.h
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/kernel/early.c
arch/s390/kernel/setup.c
arch/s390/kernel/vtime.c
arch/s390/kvm/Kconfig [new file with mode: 0644]
arch/s390/kvm/Makefile [new file with mode: 0644]
arch/s390/kvm/diag.c [new file with mode: 0644]
arch/s390/kvm/gaccess.h [new file with mode: 0644]
arch/s390/kvm/intercept.c [new file with mode: 0644]
arch/s390/kvm/interrupt.c [new file with mode: 0644]
arch/s390/kvm/kvm-s390.c [new file with mode: 0644]
arch/s390/kvm/kvm-s390.h [new file with mode: 0644]
arch/s390/kvm/priv.c [new file with mode: 0644]
arch/s390/kvm/sie64a.S [new file with mode: 0644]
arch/s390/kvm/sigp.c [new file with mode: 0644]
arch/s390/mm/pgtable.c
arch/sh/mm/init.c
arch/sparc64/mm/init.c
arch/um/drivers/chan_kern.c
arch/um/drivers/line.c
arch/um/drivers/mcast_kern.c
arch/um/drivers/mconsole_user.c
arch/um/drivers/net_kern.c
arch/um/drivers/port_user.c
arch/um/drivers/slip_kern.c
arch/um/drivers/stdio_console.c
arch/um/drivers/ubd_kern.c
arch/um/include/chan_kern.h
arch/um/kernel/um_arch.c
arch/um/os-Linux/start_up.c
arch/um/os-Linux/sys-i386/task_size.c
arch/x86/Kconfig
arch/x86/kernel/Makefile
arch/x86/kernel/apm_32.c
arch/x86/kernel/crash.c
arch/x86/kernel/kvm.c [new file with mode: 0644]
arch/x86/kernel/kvmclock.c [new file with mode: 0644]
arch/x86/kernel/mfgpt_32.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/reboot.c
arch/x86/kernel/setup_32.c
arch/x86/kernel/setup_64.c
arch/x86/kvm/Kconfig
arch/x86/kvm/Makefile
arch/x86/kvm/i8254.c [new file with mode: 0644]
arch/x86/kvm/i8254.h [new file with mode: 0644]
arch/x86/kvm/irq.c
arch/x86/kvm/irq.h
arch/x86/kvm/kvm_svm.h
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/mmu.h
arch/x86/kvm/paging_tmpl.h
arch/x86/kvm/segment_descriptor.h [deleted file]
arch/x86/kvm/svm.c
arch/x86/kvm/svm.h
arch/x86/kvm/tss.h [new file with mode: 0644]
arch/x86/kvm/vmx.c
arch/x86/kvm/vmx.h
arch/x86/kvm/x86.c
arch/x86/kvm/x86_emulate.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/ioremap.c
arch/x86/mm/pat.c
arch/x86/xen/mmu.c
block/bsg.c
drivers/acpi/processor_idle.c
drivers/acpi/thermal.c
drivers/block/brd.c
drivers/char/Kconfig
drivers/char/pcmcia/synclink_cs.c
drivers/char/rtc.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c
drivers/char/sysrq.c
drivers/char/vt.c
drivers/gpio/gpiolib.c
drivers/gpio/mcp23s08.c
drivers/gpio/pca953x.c
drivers/gpio/pcf857x.c
drivers/ide/arm/bast-ide.c
drivers/ide/arm/icside.c
drivers/ide/arm/palm_bk3710.c
drivers/ide/arm/rapide.c
drivers/ide/cris/ide-cris.c
drivers/ide/h8300/ide-h8300.c
drivers/ide/ide-acpi.c
drivers/ide/ide-cd.c
drivers/ide/ide-floppy.c
drivers/ide/ide-io.c
drivers/ide/ide-iops.c
drivers/ide/ide-pnp.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/legacy/ali14xx.c
drivers/ide/legacy/buddha.c
drivers/ide/legacy/dtc2278.c
drivers/ide/legacy/falconide.c
drivers/ide/legacy/gayle.c
drivers/ide/legacy/ht6560b.c
drivers/ide/legacy/ide-4drives.c
drivers/ide/legacy/ide-cs.c
drivers/ide/legacy/ide_platform.c
drivers/ide/legacy/macide.c
drivers/ide/legacy/q40ide.c
drivers/ide/legacy/qd65xx.c
drivers/ide/legacy/umc8672.c
drivers/ide/mips/au1xxx-ide.c
drivers/ide/mips/swarm.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/cmd640.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cy82c693.c
drivers/ide/pci/delkin_cb.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/ns87415.c
drivers/ide/pci/opti621.c
drivers/ide/pci/scc_pata.c
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/siimage.c
drivers/ide/pci/trm290.c
drivers/ide/pci/via82cxxx.c
drivers/ide/ppc/mpc8xx.c
drivers/ide/ppc/pmac.c
drivers/infiniband/hw/ehca/ehca_classes.h
drivers/infiniband/hw/ehca/ehca_irq.c
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/ehca/ehca_mrmw.c
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ehca/ehca_reqs.c
drivers/infiniband/hw/ehca/ehca_uverbs.c
drivers/infiniband/hw/ehca/hcp_if.c
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/doorbell.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/srq.c
drivers/infiniband/hw/nes/nes.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/hw/nes/nes_hw.h
drivers/infiniband/hw/nes/nes_nic.c
drivers/infiniband/hw/nes/nes_utils.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/ipoib/ipoib_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c
drivers/input/joystick/xpad.c
drivers/isdn/capi/capi.c
drivers/isdn/capi/capidrv.c
drivers/isdn/capi/capifs.c
drivers/isdn/capi/capilib.c
drivers/isdn/capi/capiutil.c
drivers/isdn/capi/kcapi.c
drivers/isdn/capi/kcapi.h
drivers/isdn/hardware/avm/b1.c
drivers/isdn/hardware/avm/b1dma.c
drivers/isdn/hardware/avm/b1isa.c
drivers/isdn/hardware/avm/b1pci.c
drivers/isdn/hardware/avm/b1pcmcia.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/avm/t1isa.c
drivers/isdn/hardware/avm/t1pci.c
drivers/isdn/hardware/eicon/divasmain.c
drivers/isdn/hardware/eicon/message.c
drivers/isdn/hisax/asuscom.c
drivers/isdn/hisax/avm_pci.c
drivers/isdn/hisax/diva.c
drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/hfc_sx.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hfcscard.c
drivers/isdn/hisax/hisax_debug.h
drivers/isdn/hisax/hisax_fcpcipnp.c
drivers/isdn/hisax/ix1_micro.c
drivers/isdn/hisax/niccy.c
drivers/isdn/hisax/sedlbauer.c
drivers/isdn/hisax/st5481.h
drivers/isdn/hisax/st5481_usb.c
drivers/isdn/hisax/teles3.c
drivers/isdn/i4l/isdn_common.c
drivers/isdn/i4l/isdn_net.h
drivers/isdn/i4l/isdn_ppp.c
drivers/isdn/i4l/isdn_tty.c
drivers/md/dm-uevent.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/md/raid6algos.c
drivers/media/video/vino.c
drivers/mfd/sm501.c
drivers/mfd/ucb1x00-ts.c
drivers/misc/enclosure.c
drivers/net/Kconfig
drivers/net/mlx4/alloc.c
drivers/net/mlx4/cq.c
drivers/net/mlx4/main.c
drivers/net/mlx4/mlx4.h
drivers/net/mlx4/qp.c
drivers/net/wireless/Makefile
drivers/net/wireless/iwlwifi/Kconfig
drivers/oprofile/buffer_sync.c
drivers/oprofile/cpu_buffer.c
drivers/oprofile/cpu_buffer.h
drivers/oprofile/oprofile_stats.c
drivers/pnp/driver.c
drivers/pnp/quirks.c
drivers/rtc/Kconfig
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-at91sam9.c
drivers/rtc/rtc-ds1302.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-ds1672.c
drivers/rtc/rtc-isl1208.c
drivers/rtc/rtc-max6900.c
drivers/rtc/rtc-max6902.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-pcf8583.c
drivers/rtc/rtc-rs5c313.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-sysfs.c
drivers/rtc/rtc-test.c
drivers/rtc/rtc-v3020.c
drivers/rtc/rtc-x1205.c
drivers/s390/Makefile
drivers/s390/block/dcssblk.c
drivers/s390/kvm/Makefile [new file with mode: 0644]
drivers/s390/kvm/kvm_virtio.c [new file with mode: 0644]
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_fsf.h
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/FlashPoint.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/aha152x.c
drivers/scsi/aha1542.c
drivers/scsi/aic7xxx/aic79xx.h
drivers/scsi/aic7xxx/aic79xx.reg
drivers/scsi/aic7xxx/aic79xx_core.c
drivers/scsi/aic7xxx/aic79xx_inline.h
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic79xx_osm.h
drivers/scsi/aic7xxx/aic79xx_osm_pci.c
drivers/scsi/aic7xxx/aic79xx_pci.c
drivers/scsi/aic7xxx/aic79xx_proc.c
drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
drivers/scsi/aic7xxx/aic7xxx.h
drivers/scsi/aic7xxx/aic7xxx.reg
drivers/scsi/aic7xxx/aic7xxx_93cx6.c
drivers/scsi/aic7xxx/aic7xxx_core.c
drivers/scsi/aic7xxx/aic7xxx_inline.h
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.h
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
drivers/scsi/aic7xxx/aic7xxx_pci.c
drivers/scsi/aic7xxx/aic7xxx_proc.c
drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped
drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
drivers/scsi/aic7xxx/aicasm/aicasm.c
drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
drivers/scsi/eata.c
drivers/scsi/esp_scsi.c
drivers/scsi/esp_scsi.h
drivers/scsi/hosts.c
drivers/scsi/ide-scsi.c
drivers/scsi/jazz_esp.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/mac_esp.c [new file with mode: 0644]
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/scsi_priv.h
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_sas.c
drivers/scsi/scsi_transport_spi.c
drivers/scsi/sgiwd93.c
drivers/scsi/sni_53c710.c
drivers/scsi/st.c
drivers/scsi/sun3x_esp.c
drivers/scsi/u14-34f.c
drivers/serial/68360serial.c
drivers/serial/8250.c
drivers/serial/8250_pci.c
drivers/serial/atmel_serial.c
drivers/serial/crisv10.c
drivers/serial/dz.c
drivers/serial/serial_core.c
drivers/serial/vr41xx_siu.c
drivers/spi/Kconfig
drivers/spi/atmel_spi.c
drivers/spi/omap_uwire.c
drivers/spi/pxa2xx_spi.c
drivers/spi/spi_bitbang.c
drivers/spi/spi_imx.c
drivers/spi/spi_mpc83xx.c
drivers/spi/spi_s3c24xx.c
drivers/spi/xilinx_spi.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/am200epd.c [new file with mode: 0644]
drivers/video/amifb.c
drivers/video/arkfb.c
drivers/video/atafb.c
drivers/video/atmel_lcdfb.c
drivers/video/aty/aty128fb.c
drivers/video/aty/atyfb_base.c
drivers/video/aty/mach64_ct.c
drivers/video/aty/radeon_base.c
drivers/video/aty/radeon_i2c.c
drivers/video/aty/radeon_monitor.c
drivers/video/aty/radeonfb.h
drivers/video/bf54x-lq043fb.c
drivers/video/cfbcopyarea.c
drivers/video/cfbfillrect.c
drivers/video/cfbimgblt.c
drivers/video/cirrusfb.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/video/fb_draw.h
drivers/video/fbmem.c
drivers/video/fsl-diu-fb.c [new file with mode: 0644]
drivers/video/fsl-diu-fb.h [new file with mode: 0644]
drivers/video/geode/Kconfig
drivers/video/geode/Makefile
drivers/video/geode/display_gx.c
drivers/video/geode/display_gx.h [deleted file]
drivers/video/geode/gxfb.h [new file with mode: 0644]
drivers/video/geode/gxfb_core.c
drivers/video/geode/lxfb.h
drivers/video/geode/lxfb_core.c
drivers/video/geode/lxfb_ops.c
drivers/video/geode/suspend_gx.c [new file with mode: 0644]
drivers/video/geode/video_gx.c
drivers/video/geode/video_gx.h [deleted file]
drivers/video/gxt4500.c
drivers/video/hecubafb.c
drivers/video/imsttfb.c
drivers/video/imxfb.c
drivers/video/intelfb/intelfb.h
drivers/video/intelfb/intelfb_i2c.c
drivers/video/intelfb/intelfbdrv.c
drivers/video/intelfb/intelfbhw.c
drivers/video/matrox/matroxfb_DAC1064.c
drivers/video/matrox/matroxfb_Ti3026.c
drivers/video/matrox/matroxfb_accel.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/matrox/matroxfb_maven.c
drivers/video/matrox/matroxfb_misc.c
drivers/video/metronomefb.c
drivers/video/modedb.c
drivers/video/n411.c [new file with mode: 0644]
drivers/video/nvidia/nv_hw.c
drivers/video/nvidia/nv_setup.c
drivers/video/nvidia/nvidia.c
drivers/video/offb.c
drivers/video/pm2fb.c
drivers/video/pm3fb.c
drivers/video/riva/fbdev.c
drivers/video/riva/nv_driver.c
drivers/video/riva/riva_hw.c
drivers/video/s3c2410fb.c
drivers/video/s3fb.c
drivers/video/sa1100fb.h
drivers/video/savage/savagefb-i2c.c
drivers/video/sis/sis.h
drivers/video/sstfb.c
drivers/video/stifb.c
drivers/video/syscopyarea.c
drivers/video/sysfillrect.c
drivers/video/sysimgblt.c
drivers/video/tdfxfb.c
drivers/video/tridentfb.c
drivers/video/uvesafb.c
drivers/video/vermilion/vermilion.c
drivers/video/vt8623fb.c
drivers/video/w100fb.c
fs/aio.c
fs/buffer.c
fs/dquot.c
fs/ext2/balloc.c
fs/ext2/dir.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/super.c
fs/ext2/xattr.c
fs/ext2/xip.c
fs/ext2/xip.h
fs/ext3/balloc.c
fs/ext3/ext3_jbd.c
fs/ext3/fsync.c
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/namei.c
fs/ext3/resize.c
fs/ext3/super.c
fs/ext3/xattr.c
fs/ext3/xattr.h
fs/ext4/super.c
fs/fat/dir.c
fs/fat/fatent.c
fs/fat/file.c
fs/fat/inode.c
fs/gfs2/ops_address.c
fs/hugetlbfs/inode.c
fs/jbd/commit.c
fs/jbd/journal.c
fs/jbd/revoke.c
fs/jbd/transaction.c
fs/msdos/namei.c
fs/namespace.c
fs/ncpfs/inode.c
fs/ncpfs/ioctl.c
fs/ncpfs/ncpsign_kernel.c
fs/open.c
fs/partitions/msdos.c
fs/proc/proc_misc.c
fs/proc/task_mmu.c
fs/quota.c
fs/quota_v1.c
fs/quota_v2.c
fs/reiserfs/bitmap.c
fs/reiserfs/do_balan.c
fs/reiserfs/ioctl.c
fs/reiserfs/journal.c
fs/reiserfs/namei.c
fs/reiserfs/objectid.c
fs/reiserfs/stree.c
fs/reiserfs/super.c
fs/super.c
fs/sysfs/file.c
fs/sysfs/group.c
fs/sysfs/sysfs.h
fs/udf/namei.c
fs/ufs/balloc.c
fs/ufs/dir.c
fs/ufs/inode.c
fs/ufs/swab.h
fs/ufs/ufs.h
fs/vfat/namei.c
include/asm-alpha/bug.h
include/asm-alpha/byteorder.h
include/asm-alpha/pgtable.h
include/asm-arm/arch-sa1100/ide.h
include/asm-arm/pgtable.h
include/asm-avr32/pgtable.h
include/asm-cris/arch-v10/ide.h
include/asm-cris/pgtable.h
include/asm-frv/pgtable.h
include/asm-generic/gpio.h
include/asm-ia64/gcc_intrin.h
include/asm-ia64/hugetlb.h [new file with mode: 0644]
include/asm-ia64/kvm.h
include/asm-ia64/kvm_host.h [new file with mode: 0644]
include/asm-ia64/kvm_para.h [new file with mode: 0644]
include/asm-ia64/page.h
include/asm-ia64/pgtable.h
include/asm-ia64/processor.h
include/asm-m32r/pgtable.h
include/asm-m68k/motorola_pgtable.h
include/asm-m68k/sun3_pgtable.h
include/asm-mips/pgtable.h
include/asm-mips/vr41xx/siu.h
include/asm-mips/vr41xx/vr41xx.h
include/asm-mn10300/pgtable.h
include/asm-parisc/pgtable.h
include/asm-powerpc/hugetlb.h [new file with mode: 0644]
include/asm-powerpc/kvm.h
include/asm-powerpc/kvm_asm.h [new file with mode: 0644]
include/asm-powerpc/kvm_host.h [new file with mode: 0644]
include/asm-powerpc/kvm_para.h [new file with mode: 0644]
include/asm-powerpc/kvm_ppc.h [new file with mode: 0644]
include/asm-powerpc/mmu-44x.h
include/asm-powerpc/page_64.h
include/asm-powerpc/pgtable-ppc32.h
include/asm-powerpc/pgtable-ppc64.h
include/asm-ppc/pgtable.h
include/asm-s390/Kbuild
include/asm-s390/kvm.h
include/asm-s390/kvm_host.h [new file with mode: 0644]
include/asm-s390/kvm_para.h [new file with mode: 0644]
include/asm-s390/kvm_virtio.h [new file with mode: 0644]
include/asm-s390/lowcore.h
include/asm-s390/mmu.h
include/asm-s390/mmu_context.h
include/asm-s390/pgtable.h
include/asm-s390/setup.h
include/asm-sh/hugetlb.h [new file with mode: 0644]
include/asm-sh/pgtable_32.h
include/asm-sh/pgtable_64.h
include/asm-sparc/pgtable.h
include/asm-sparc64/hugetlb.h [new file with mode: 0644]
include/asm-sparc64/page.h
include/asm-sparc64/pgtable.h
include/asm-um/pgtable.h
include/asm-x86/geode.h
include/asm-x86/hugetlb.h [new file with mode: 0644]
include/asm-x86/kvm.h
include/asm-x86/kvm_host.h
include/asm-x86/kvm_para.h
include/asm-x86/pgtable.h
include/asm-x86/processor.h
include/asm-x86/reboot.h
include/asm-xtensa/pgtable.h
include/linux/bitmap.h
include/linux/bootmem.h
include/linux/bsg.h
include/linux/cache.h
include/linux/capability.h
include/linux/cpumask.h
include/linux/cpuset.h
include/linux/dmi.h
include/linux/fb.h
include/linux/fs.h
include/linux/gfp.h
include/linux/hugetlb.h
include/linux/i2o.h
include/linux/ide.h
include/linux/init_task.h
include/linux/kprobes.h
include/linux/kvm.h
include/linux/kvm_host.h
include/linux/kvm_para.h
include/linux/kvm_types.h
include/linux/list.h
include/linux/memory_hotplug.h
include/linux/mempolicy.h
include/linux/mlx4/device.h
include/linux/mlx4/qp.h
include/linux/mm.h
include/linux/mm_types.h
include/linux/mmzone.h
include/linux/msdos_fs.h
include/linux/ncp_fs.h
include/linux/nodemask.h
include/linux/notifier.h
include/linux/oom.h
include/linux/page-flags.h
include/linux/prctl.h
include/linux/quota.h
include/linux/quotaops.h
include/linux/raid/raid5.h
include/linux/reiserfs_fs.h
include/linux/sched.h
include/linux/securebits.h
include/linux/security.h
include/linux/serial_8250.h
include/linux/shmem_fs.h
include/linux/suspend.h
include/linux/swap.h
include/linux/synclink.h
include/linux/sysfs.h
include/linux/vmalloc.h
include/linux/vmstat.h
include/net/compat.h
include/scsi/scsi_device.h
include/video/atmel_lcdc.h
include/video/hecubafb.h [new file with mode: 0644]
include/video/metronomefb.h [new file with mode: 0644]
init/Kconfig
ipc/shm.c
kernel/bounds.c [new file with mode: 0644]
kernel/cpuset.c
kernel/exit.c
kernel/fork.c
kernel/hrtimer.c
kernel/kexec.c
kernel/kprobes.c
kernel/power/console.c
kernel/sys.c
lib/bitmap.c
lib/radix-tree.c
mm/Kconfig
mm/bootmem.c
mm/dmapool.c
mm/fadvise.c
mm/filemap.c
mm/filemap_xip.c
mm/hugetlb.c
mm/internal.h
mm/madvise.c
mm/memory.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/mincore.c
mm/mmap.c
mm/mmzone.c
mm/nommu.c
mm/oom_kill.c
mm/page_alloc.c
mm/pagewalk.c
mm/rmap.c
mm/shmem.c
mm/slab.c
mm/slub.c
mm/sparse.c
mm/swap.c
mm/swapfile.c
mm/truncate.c
mm/vmalloc.c
mm/vmscan.c
mm/vmstat.c
net/can/raw.c
net/compat.c
net/ipv4/ip_sockglue.c
net/ipv4/tcp_input.c
net/ipv6/Kconfig
net/ipv6/ip6mr.c
net/ipv6/ipv6_sockglue.c
net/mac80211/Kconfig
net/mac80211/mesh.h
net/mac80211/mesh_hwmp.c
net/sunrpc/xprt.c
net/tipc/msg.h
net/xfrm/xfrm_algo.c
net/xfrm/xfrm_state.c
scripts/kernel-doc
security/capability.c
security/commoncap.c
security/dummy.c
security/root_plug.c
security/security.c
security/selinux/hooks.c
security/smack/smack_lsm.c
security/smack/smackfs.c
virt/kvm/kvm_main.c
virt/kvm/kvm_trace.c [new file with mode: 0644]

index 488dd4a..617c2d9 100644 (file)
@@ -645,4 +645,58 @@ X!Idrivers/video/console/fonts.c
 !Edrivers/i2c/i2c-core.c
   </chapter>
 
+  <chapter id="clk">
+     <title>Clock Framework</title>
+
+     <para>
+       The clock framework defines programming interfaces to support
+       software management of the system clock tree.
+       This framework is widely used with System-On-Chip (SOC) platforms
+       to support power management and various devices which may need
+       custom clock rates.
+       Note that these "clocks" don't relate to timekeeping or real
+       time clocks (RTCs), each of which have separate frameworks.
+       These <structname>struct clk</structname> instances may be used
+       to manage for example a 96 MHz signal that is used to shift bits
+       into and out of peripherals or busses, or otherwise trigger
+       synchronous state machine transitions in system hardware.
+     </para>
+
+     <para>
+       Power management is supported by explicit software clock gating:
+       unused clocks are disabled, so the system doesn't waste power
+       changing the state of transistors that aren't in active use.
+       On some systems this may be backed by hardware clock gating,
+       where clocks are gated without being disabled in software.
+       Sections of chips that are powered but not clocked may be able
+       to retain their last state.
+       This low power state is often called a <emphasis>retention
+       mode</emphasis>.
+       This mode still incurs leakage currents, especially with finer
+       circuit geometries, but for CMOS circuits power is mostly used
+       by clocked state changes.
+     </para>
+
+     <para>
+       Power-aware drivers only enable their clocks when the device
+       they manage is in active use.  Also, system sleep states often
+       differ according to which clock domains are active:  while a
+       "standby" state may allow wakeup from several active domains, a
+       "mem" (suspend-to-RAM) state may require a more wholesale shutdown
+       of clocks derived from higher speed PLLs and oscillators, limiting
+       the number of possible wakeup event sources.  A driver's suspend
+       method may need to be aware of system-specific clock constraints
+       on the target sleep state.
+     </para>
+
+     <para>
+        Some platforms support programmable clock generators.  These
+       can be used by external chips of various kinds, such as other
+       CPUs, multimedia codecs, and devices with strict requirements
+       for interface clocking.
+     </para>
+
+!Iinclude/linux/clk.h
+  </chapter>
+
 </book>
diff --git a/Documentation/fb/gxfb.txt b/Documentation/fb/gxfb.txt
new file mode 100644 (file)
index 0000000..2f64090
--- /dev/null
@@ -0,0 +1,52 @@
+[This file is cloned from VesaFB/aty128fb]
+
+What is gxfb?
+=================
+
+This is a graphics framebuffer driver for AMD Geode GX2 based processors.
+
+Advantages:
+
+ * No need to use AMD's VSA code (or other VESA emulation layer) in the
+   BIOS.
+ * It provides a nice large console (128 cols + 48 lines with 1024x768)
+   without using tiny, unreadable fonts.
+ * You can run XF68_FBDev on top of /dev/fb0
+ * Most important: boot logo :-)
+
+Disadvantages:
+
+ * graphic mode is slower than text mode...
+
+
+How to use it?
+==============
+
+Switching modes is done using  gxfb.mode_option=<resolution>... boot
+parameter or using `fbset' program.
+
+See Documentation/fb/modedb.txt for more information on modedb
+resolutions.
+
+
+X11
+===
+
+XF68_FBDev should generally work fine, but it is non-accelerated.
+
+
+Configuration
+=============
+
+You can pass kernel command line options to gxfb with gxfb.<option>.
+For example, gxfb.mode_option=800x600@75.
+Accepted options:
+
+mode_option    - specify the video mode.  Of the form
+                 <x>x<y>[-<bpp>][@<refresh>]
+vram           - size of video ram (normally auto-detected)
+vt_switch      - enable vt switching during suspend/resume.  The vt
+                 switch is slow, but harmless.
+
+--
+Andres Salomon <dilinger@debian.org>
index da5ee74..27a3160 100644 (file)
@@ -14,6 +14,8 @@ graphics devices.  These would include:
        Intel 915GM
        Intel 945G
        Intel 945GM
+       Intel 965G
+       Intel 965GM
 
 B.  List of available options
 
diff --git a/Documentation/fb/lxfb.txt b/Documentation/fb/lxfb.txt
new file mode 100644 (file)
index 0000000..38b3ca6
--- /dev/null
@@ -0,0 +1,52 @@
+[This file is cloned from VesaFB/aty128fb]
+
+What is lxfb?
+=================
+
+This is a graphics framebuffer driver for AMD Geode LX based processors.
+
+Advantages:
+
+ * No need to use AMD's VSA code (or other VESA emulation layer) in the
+   BIOS.
+ * It provides a nice large console (128 cols + 48 lines with 1024x768)
+   without using tiny, unreadable fonts.
+ * You can run XF68_FBDev on top of /dev/fb0
+ * Most important: boot logo :-)
+
+Disadvantages:
+
+ * graphic mode is slower than text mode...
+
+
+How to use it?
+==============
+
+Switching modes is done using  lxfb.mode_option=<resolution>... boot
+parameter or using `fbset' program.
+
+See Documentation/fb/modedb.txt for more information on modedb
+resolutions.
+
+
+X11
+===
+
+XF68_FBDev should generally work fine, but it is non-accelerated.
+
+
+Configuration
+=============
+
+You can pass kernel command line options to lxfb with lxfb.<option>.
+For example, lxfb.mode_option=800x600@75.
+Accepted options:
+
+mode_option    - specify the video mode.  Of the form
+                 <x>x<y>[-<bpp>][@<refresh>]
+vram           - size of video ram (normally auto-detected)
+vt_switch      - enable vt switching during suspend/resume.  The vt
+                 switch is slow, but harmless.
+
+--
+Andres Salomon <dilinger@debian.org>
index b9a2e7b..237ca41 100644 (file)
@@ -1,7 +1,7 @@
                        Metronomefb
                        -----------
 Maintained by Jaya Kumar <jayakumar.lkml.gmail.com>
-Last revised: Nov 20, 2007
+Last revised: Mar 10, 2008
 
 Metronomefb is a driver for the Metronome display controller. The controller
 is from E-Ink Corporation. It is intended to be used to drive the E-Ink
@@ -11,20 +11,18 @@ display media here http://www.e-ink.com/products/matrix/metronome.html .
 Metronome is interfaced to the host CPU through the AMLCD interface. The
 host CPU generates the control information and the image in a framebuffer
 which is then delivered to the AMLCD interface by a host specific method.
-Currently, that's implemented for the PXA's LCDC controller. The display and
-error status are each pulled through individual GPIOs.
+The display and error status are each pulled through individual GPIOs.
 
-Metronomefb was written for the PXA255/gumstix/lyre combination and
-therefore currently has board set specific code in it. If other boards based on
-other architectures are available, then the host specific code can be separated
-and abstracted out.
+Metronomefb is platform independent and depends on a board specific driver
+to do all physical IO work. Currently, an example is implemented for the
+PXA board used in the AM-200 EPD devkit. This example is am200epd.c
 
 Metronomefb requires waveform information which is delivered via the AMLCD
 interface to the metronome controller. The waveform information is expected to
 be delivered from userspace via the firmware class interface. The waveform file
 can be compressed as long as your udev or hotplug script is aware of the need
-to uncompress it before delivering it. metronomefb will ask for waveform.wbf
-which would typically go into /lib/firmware/waveform.wbf depending on your
+to uncompress it before delivering it. metronomefb will ask for metronome.wbf
+which would typically go into /lib/firmware/metronome.wbf depending on your
 udev/hotplug setup. I have only tested with a single waveform file which was
 originally labeled 23P01201_60_WT0107_MTC. I do not know what it stands for.
 Caution should be exercised when manipulating the waveform as there may be
index 4fcdb4c..ec4dee7 100644 (file)
@@ -125,8 +125,12 @@ There may be more modes.
     amifb      - Amiga chipset frame buffer
     aty128fb   - ATI Rage128 / Pro frame buffer
     atyfb      - ATI Mach64 frame buffer
+    pm2fb      - Permedia 2/2V frame buffer
+    pm3fb      - Permedia 3 frame buffer
+    sstfb      - Voodoo 1/2 (SST1) chipset frame buffer
     tdfxfb     - 3D Fx frame buffer
     tridentfb  - Trident (Cyber)blade chipset frame buffer
+    vt8623fb   - VIA 8623 frame buffer
 
 BTW, only a few drivers use this at the moment. Others are to follow
 (feel free to send patches).
index 448729f..599fe55 100644 (file)
@@ -128,15 +128,6 @@ Who:       Arjan van de Ven <arjan@linux.intel.com>
 
 ---------------------------
 
-What:  vm_ops.nopage
-When:  Soon, provided in-kernel callers have been converted
-Why:   This interface is replaced by vm_ops.fault, but it has been around
-       forever, is used by a lot of drivers, and doesn't cost much to
-       maintain.
-Who:   Nick Piggin <npiggin@suse.de>
-
----------------------------
-
 What:  PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
 When:  October 2008
 Why:   The stacking of class devices makes these values misleading and
index 42d4b30..c2992bc 100644 (file)
@@ -511,7 +511,6 @@ prototypes:
        void (*open)(struct vm_area_struct*);
        void (*close)(struct vm_area_struct*);
        int (*fault)(struct vm_area_struct*, struct vm_fault *);
-       struct page *(*nopage)(struct vm_area_struct*, unsigned long, int *);
        int (*page_mkwrite)(struct vm_area_struct *, struct page *);
 
 locking rules:
@@ -519,7 +518,6 @@ locking rules:
 open:          no      yes
 close:         no      yes
 fault:         no      yes
-nopage:                no      yes
 page_mkwrite:  no      yes             no
 
        ->page_mkwrite() is called when a previously read-only page is
@@ -537,4 +535,3 @@ NULL.
 
 ipc/shm.c::shm_delete() - may need BKL.
 ->read() and ->write() in many drivers are (probably) missing BKL.
-drivers/sgi/char/graphics.c::sgi_graphics_nopage() - may need BKL.
index 145e440..222437e 100644 (file)
@@ -92,6 +92,18 @@ NodeList format is a comma-separated list of decimal numbers and ranges,
 a range being two hyphen-separated decimal numbers, the smallest and
 largest node numbers in the range.  For example, mpol=bind:0-3,5,7,9-15
 
+NUMA memory allocation policies have optional flags that can be used in
+conjunction with their modes.  These optional flags can be specified
+when tmpfs is mounted by appending them to the mode before the NodeList.
+See Documentation/vm/numa_memory_policy.txt for a list of all available
+memory allocation policy mode flags.
+
+       =static         is equivalent to        MPOL_F_STATIC_NODES
+       =relative       is equivalent to        MPOL_F_RELATIVE_NODES
+
+For example, mpol=bind=static:NodeList, is the equivalent of an
+allocation policy of MPOL_BIND | MPOL_F_STATIC_NODES.
+
 Note that trying to mount a tmpfs with an mpol option will fail if the
 running kernel does not support NUMA; and will fail if its nodelist
 specifies a node which is not online.  If your system relies on that
index fcc123f..2d5e1e5 100644 (file)
@@ -17,6 +17,21 @@ dmask=###     -- The permission mask for the directory.
 fmask=###     -- The permission mask for files.
                  The default is the umask of current process.
 
+allow_utime=### -- This option controls the permission check of mtime/atime.
+
+                  20 - If current process is in group of file's group ID,
+                       you can change timestamp.
+                   2 - Other users can change timestamp.
+
+                 The default is set from `dmask' option. (If the directory is
+                 writable, utime(2) is also allowed. I.e. ~dmask & 022)
+
+                 Normally utime(2) checks current process is owner of
+                 the file, or it has CAP_FOWNER capability.  But FAT
+                 filesystem doesn't have uid/gid on disk, so normal
+                 check is too unflexible. With this option you can
+                 relax it.
+
 codepage=###  -- Sets the codepage number for converting to shortname
                 characters on FAT filesystem.
                 By default, FAT_DEFAULT_CODEPAGE setting is used.
index 5463009..c35ca9e 100644 (file)
@@ -107,6 +107,16 @@ type of GPIO controller, and on one particular board 80-95 with an FPGA.
 The numbers need not be contiguous; either of those platforms could also
 use numbers 2000-2063 to identify GPIOs in a bank of I2C GPIO expanders.
 
+If you want to initialize a structure with an invalid GPIO number, use
+some negative number (perhaps "-EINVAL"); that will never be valid.  To
+test if a number could reference a GPIO, you may use this predicate:
+
+       int gpio_is_valid(int number);
+
+A number that's not valid will be rejected by calls which may request
+or free GPIOs (see below).  Other numbers may also be rejected; for
+example, a number might be valid but unused on a given board.
+
 Whether a platform supports multiple GPIO controllers is currently a
 platform-specific implementation issue.
 
diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt
new file mode 100644 (file)
index 0000000..bec9d81
--- /dev/null
@@ -0,0 +1,82 @@
+Currently, kvm module in EXPERIMENTAL stage on IA64. This means that
+interfaces are not stable enough to use. So, plase had better don't run
+critical applications in virtual machine. We will try our best to make it
+strong in future versions!
+                               Guide: How to boot up guests on kvm/ia64
+
+This guide is to describe how to enable kvm support for IA-64 systems.
+
+1. Get the kvm source from git.kernel.org.
+       Userspace source:
+               git clone git://git.kernel.org/pub/scm/virt/kvm/kvm-userspace.git
+       Kernel Source:
+               git clone git://git.kernel.org/pub/scm/linux/kernel/git/xiantao/kvm-ia64.git
+
+2. Compile the source code.
+       2.1 Compile userspace code:
+               (1)cd ./kvm-userspace
+               (2)./configure
+               (3)cd kernel
+               (4)make sync LINUX= $kernel_dir (kernel_dir is the directory of kernel source.)
+               (5)cd ..
+               (6)make qemu
+               (7)cd qemu; make install
+
+       2.2 Compile kernel source code:
+               (1) cd ./$kernel_dir
+               (2) Make menuconfig
+               (3) Enter into virtualization option, and choose kvm.
+               (4) make
+               (5) Once (4) done, make modules_install
+               (6) Make initrd, and use new kernel to reboot up host machine.
+               (7) Once (6) done, cd $kernel_dir/arch/ia64/kvm
+               (8) insmod kvm.ko; insmod kvm-intel.ko
+
+Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qemu, otherwise, may fail.
+
+3. Get Guest Firmware named as Flash.fd, and put it under right place:
+       (1) If you have the guest firmware (binary) released by Intel Corp for Xen, use it directly.
+
+       (2) If you have no firmware at hand, Please download its source from
+               hg clone http://xenbits.xensource.com/ext/efi-vfirmware.hg
+           you can get the firmware's binary in the directory of efi-vfirmware.hg/binaries.
+
+       (3) Rename the firware you owned to Flash.fd, and copy it to /usr/local/share/qemu
+
+4. Boot up Linux or Windows guests:
+       4.1 Create or install a image for guest boot. If you have xen experience, it should be easy.
+
+       4.2 Boot up guests use the following command.
+               /usr/local/bin/qemu-system-ia64 -smp xx -m 512 -hda $your_image
+               (xx is the number of virtual processors for the guest, now the maximum value is 4)
+
+5. Known possibile issue on some platforms with old Firmware.
+
+If meet strange host crashe issues, try to solve it through either of the following ways:
+
+(1): Upgrade your Firmware to the latest one.
+
+(2): Applying the below patch to kernel source.
+diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S
+index 0b53344..f02b0f7 100644
+--- a/arch/ia64/kernel/pal.S
++++ b/arch/ia64/kernel/pal.S
+@@ -84,7 +84,8 @@ GLOBAL_ENTRY(ia64_pal_call_static)
+       mov ar.pfs = loc1
+       mov rp = loc0
+       ;;
+-      srlz.d                          // seralize restoration of psr.l
++      srlz.i                  // seralize restoration of psr.l
++      ;;
+       br.ret.sptk.many b0
+ END(ia64_pal_call_static)
+
+6. Bug report:
+       If you found any issues when use kvm/ia64, Please post the bug info to kvm-ia64-devel mailing list.
+       https://lists.sourceforge.net/lists/listinfo/kvm-ia64-devel/
+
+Thanks for your interest! Let's work together, and make kvm/ia64 stronger and stronger!
+
+
+                                                               Xiantao Zhang <xiantao.zhang@intel.com>
+                                                                                       2008.3.10
index 658f271..3f348a0 100644 (file)
-/*
- * IDE ATAPI streaming tape driver.
- *
- * This driver is a part of the Linux ide driver.
- *
- * The driver, in co-operation with ide.c, basically traverses the
- * request-list for the block device interface. The character device
- * interface, on the other hand, creates new requests, adds them
- * to the request-list of the block device, and waits for their completion.
- *
- * Pipelined operation mode is now supported on both reads and writes.
- *
- * The block device major and minor numbers are determined from the
- * tape's relative position in the ide interfaces, as explained in ide.c.
- *
- * The character device interface consists of the following devices:
- *
- * ht0         major 37, minor 0       first  IDE tape, rewind on close.
- * ht1         major 37, minor 1       second IDE tape, rewind on close.
- * ...
- * nht0                major 37, minor 128     first  IDE tape, no rewind on close.
- * nht1                major 37, minor 129     second IDE tape, no rewind on close.
- * ...
- *
- * The general magnetic tape commands compatible interface, as defined by
- * include/linux/mtio.h, is accessible through the character device.
- *
- * General ide driver configuration options, such as the interrupt-unmask
- * flag, can be configured by issuing an ioctl to the block device interface,
- * as any other ide device.
- *
- * Our own ide-tape ioctl's can be issued to either the block device or
- * the character device interface.
- *
- * Maximal throughput with minimal bus load will usually be achieved in the
- * following scenario:
- *
- *     1.      ide-tape is operating in the pipelined operation mode.
- *     2.      No buffering is performed by the user backup program.
- *
- * Testing was done with a 2 GB CONNER CTMA 4000 IDE ATAPI Streaming Tape Drive.
- *
- * Here are some words from the first releases of hd.c, which are quoted
- * in ide.c and apply here as well:
- *
- * | Special care is recommended.  Have Fun!
- *
- *
- * An overview of the pipelined operation mode.
- *
- * In the pipelined write mode, we will usually just add requests to our
- * pipeline and return immediately, before we even start to service them. The
- * user program will then have enough time to prepare the next request while
- * we are still busy servicing previous requests. In the pipelined read mode,
- * the situation is similar - we add read-ahead requests into the pipeline,
- * before the user even requested them.
- *
- * The pipeline can be viewed as a "safety net" which will be activated when
- * the system load is high and prevents the user backup program from keeping up
- * with the current tape speed. At this point, the pipeline will get
- * shorter and shorter but the tape will still be streaming at the same speed.
- * Assuming we have enough pipeline stages, the system load will hopefully
- * decrease before the pipeline is completely empty, and the backup program
- * will be able to "catch up" and refill the pipeline again.
- *
- * When using the pipelined mode, it would be best to disable any type of
- * buffering done by the user program, as ide-tape already provides all the
- * benefits in the kernel, where it can be done in a more efficient way.
- * As we will usually not block the user program on a request, the most
- * efficient user code will then be a simple read-write-read-... cycle.
- * Any additional logic will usually just slow down the backup process.
- *
- * Using the pipelined mode, I get a constant over 400 KBps throughput,
- * which seems to be the maximum throughput supported by my tape.
- *
- * However, there are some downfalls:
- *
- *     1.      We use memory (for data buffers) in proportional to the number
- *             of pipeline stages (each stage is about 26 KB with my tape).
- *     2.      In the pipelined write mode, we cheat and postpone error codes
- *             to the user task. In read mode, the actual tape position
- *             will be a bit further than the last requested block.
- *
- * Concerning (1):
- *
- *     1.      We allocate stages dynamically only when we need them. When
- *             we don't need them, we don't consume additional memory. In
- *             case we can't allocate stages, we just manage without them
- *             (at the expense of decreased throughput) so when Linux is
- *             tight in memory, we will not pose additional difficulties.
- *
- *     2.      The maximum number of stages (which is, in fact, the maximum
- *             amount of memory) which we allocate is limited by the compile
- *             time parameter IDETAPE_MAX_PIPELINE_STAGES.
- *
- *     3.      The maximum number of stages is a controlled parameter - We
- *             don't start from the user defined maximum number of stages
- *             but from the lower IDETAPE_MIN_PIPELINE_STAGES (again, we
- *             will not even allocate this amount of stages if the user
- *             program can't handle the speed). We then implement a feedback
- *             loop which checks if the pipeline is empty, and if it is, we
- *             increase the maximum number of stages as necessary until we
- *             reach the optimum value which just manages to keep the tape
- *             busy with minimum allocated memory or until we reach
- *             IDETAPE_MAX_PIPELINE_STAGES.
- *
- * Concerning (2):
- *
- *     In pipelined write mode, ide-tape can not return accurate error codes
- *     to the user program since we usually just add the request to the
- *      pipeline without waiting for it to be serviced. In case an error
- *      occurs, I will report it on the next user request.
- *
- *     In the pipelined read mode, subsequent read requests or forward
- *     filemark spacing will perform correctly, as we preserve all blocks
- *     and filemarks which we encountered during our excess read-ahead.
- *
- *     For accurate tape positioning and error reporting, disabling
- *     pipelined mode might be the best option.
- *
- * You can enable/disable/tune the pipelined operation mode by adjusting
- * the compile time parameters below.
- *
- *
- *     Possible improvements.
- *
- *     1.      Support for the ATAPI overlap protocol.
- *
- *             In order to maximize bus throughput, we currently use the DSC
- *             overlap method which enables ide.c to service requests from the
- *             other device while the tape is busy executing a command. The
- *             DSC overlap method involves polling the tape's status register
- *             for the DSC bit, and servicing the other device while the tape
- *             isn't ready.
- *
- *             In the current QIC development standard (December 1995),
- *             it is recommended that new tape drives will *in addition*
- *             implement the ATAPI overlap protocol, which is used for the
- *             same purpose - efficient use of the IDE bus, but is interrupt
- *             driven and thus has much less CPU overhead.
- *
- *             ATAPI overlap is likely to be supported in most new ATAPI
- *             devices, including new ATAPI cdroms, and thus provides us
- *             a method by which we can achieve higher throughput when
- *             sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
- */
+IDE ATAPI streaming tape driver.
+
+This driver is a part of the Linux ide driver.
+
+The driver, in co-operation with ide.c, basically traverses the
+request-list for the block device interface. The character device
+interface, on the other hand, creates new requests, adds them
+to the request-list of the block device, and waits for their completion.
+
+The block device major and minor numbers are determined from the
+tape's relative position in the ide interfaces, as explained in ide.c.
+
+The character device interface consists of the following devices:
+
+ht0            major 37, minor 0       first  IDE tape, rewind on close.
+ht1            major 37, minor 1       second IDE tape, rewind on close.
+...
+nht0           major 37, minor 128     first  IDE tape, no rewind on close.
+nht1           major 37, minor 129     second IDE tape, no rewind on close.
+...
+
+The general magnetic tape commands compatible interface, as defined by
+include/linux/mtio.h, is accessible through the character device.
+
+General ide driver configuration options, such as the interrupt-unmask
+flag, can be configured by issuing an ioctl to the block device interface,
+as any other ide device.
+
+Our own ide-tape ioctl's can be issued to either the block device or
+the character device interface.
+
+Maximal throughput with minimal bus load will usually be achieved in the
+following scenario:
+
+     1.        ide-tape is operating in the pipelined operation mode.
+     2.        No buffering is performed by the user backup program.
+
+Testing was done with a 2 GB CONNER CTMA 4000 IDE ATAPI Streaming Tape Drive.
+
+Here are some words from the first releases of hd.c, which are quoted
+in ide.c and apply here as well:
+
+| Special care is recommended.  Have Fun!
+
+Possible improvements:
+
+1. Support for the ATAPI overlap protocol.
+
+In order to maximize bus throughput, we currently use the DSC
+overlap method which enables ide.c to service requests from the
+other device while the tape is busy executing a command. The
+DSC overlap method involves polling the tape's status register
+for the DSC bit, and servicing the other device while the tape
+isn't ready.
+
+In the current QIC development standard (December 1995),
+it is recommended that new tape drives will *in addition*
+implement the ATAPI overlap protocol, which is used for the
+same purpose - efficient use of the IDE bus, but is interrupt
+driven and thus has much less CPU overhead.
+
+ATAPI overlap is likely to be supported in most new ATAPI
+devices, including new ATAPI cdroms, and thus provides us
+a method by which we can achieve higher throughput when
+sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
index 486c699..0c78f4b 100644 (file)
@@ -82,27 +82,26 @@ Drives are normally found by auto-probing and/or examining the CMOS/BIOS data.
 For really weird situations, the apparent (fdisk) geometry can also be specified
 on the kernel "command line" using LILO.  The format of such lines is:
 
-       hdx=cyls,heads,sects
-or     hdx=cdrom
+       ide_core.chs=[interface_number.device_number]:cyls,heads,sects
+or     ide_core.cdrom=[interface_number.device_number]
 
-where hdx can be any of hda through hdh, Three values are required
-(cyls,heads,sects).  For example:
+For example:
 
-       hdc=1050,32,64  hdd=cdrom
+       ide_core.chs=1.0:1050,32,64  ide_core.cdrom=1.1
 
-either {hda,hdb} or {hdc,hdd}.  The results of successful auto-probing may
-override the physical geometry/irq specified, though the "original" geometry
-may be retained as the "logical" geometry for partitioning purposes (fdisk).
+The results of successful auto-probing may override the physical geometry/irq
+specified, though the "original" geometry may be retained as the "logical"
+geometry for partitioning purposes (fdisk).
 
 If the auto-probing during boot time confuses a drive (ie. the drive works
 with hd.c but not with ide.c), then an command line option may be specified
 for each drive for which you'd like the drive to skip the hardware
 probe/identification sequence.  For example:
 
-       hdb=noprobe
+       ide_core.noprobe=0.1
 or
-       hdc=768,16,32
-       hdc=noprobe
+       ide_core.chs=1.0:768,16,32
+       ide_core.noprobe=1.0
 
 Note that when only one IDE device is attached to an interface, it should be
 jumpered as "single" or "master", *not* "slave".  Many folks have had
@@ -118,9 +117,9 @@ If for some reason your cdrom drive is *not* found at boot time, you can force
 the probe to look harder by supplying a kernel command line parameter
 via LILO, such as:
 
-       hdc=cdrom       /* hdc = "master" on second interface */
+       ide_core.cdrom=1.0      /* "master" on second interface (hdc) */
 or
-       hdd=cdrom       /* hdd = "slave" on second interface */
+       ide_core.cdrom=1.1      /* "slave" on second interface (hdd) */
 
 For example, a GW2000 system might have a hard drive on the primary
 interface (/dev/hda) and an IDE cdrom drive on the secondary interface
@@ -174,9 +173,7 @@ to /etc/modprobe.conf.
 
 When ide.c is used as a module, you can pass command line parameters to the
 driver using the "options=" keyword to insmod, while replacing any ',' with
-';'.  For example:
-
-       insmod ide.o options="hda=nodma hdb=nodma"
+';'.
 
 
 ================================================================================
@@ -184,57 +181,6 @@ driver using the "options=" keyword to insmod, while replacing any ',' with
 Summary of ide driver parameters for kernel command line
 --------------------------------------------------------
 
- "hdx="  is recognized for all "x" from "a" to "u", such as "hdc".
-
- "idex=" is recognized for all "x" from "0" to "9", such as "ide1".
-
- "hdx=noprobe"         : drive may be present, but do not probe for it
-
- "hdx=none"            : drive is NOT present, ignore cmos and do not probe
-
- "hdx=nowerr"          : ignore the WRERR_STAT bit on this drive
-
- "hdx=cdrom"           : drive is present, and is a cdrom drive
-
- "hdx=cyl,head,sect"   : disk drive is present, with specified geometry
-
- "hdx=autotune"                : driver will attempt to tune interface speed
-                         to the fastest PIO mode supported,
-                         if possible for this drive only.
-                         Not fully supported by all chipset types,
-                         and quite likely to cause trouble with
-                         older/odd IDE drives.
-
- "hdx=nodma"           : disallow DMA
-
- "idebus=xx"           : inform IDE driver of VESA/PCI bus speed in MHz,
-                         where "xx" is between 20 and 66 inclusive,
-                         used when tuning chipset PIO modes.
-                         For PCI bus, 25 is correct for a P75 system,
-                         30 is correct for P90,P120,P180 systems,
-                         and 33 is used for P100,P133,P166 systems.
-                         If in doubt, use idebus=33 for PCI.
-                         As for VLB, it is safest to not specify it.
-                         Bigger values are safer than smaller ones.
-
- "idex=serialize"      : do not overlap operations on idex. Please note
-                         that you will have to specify this option for
-                         both the respective primary and secondary channel
-                         to take effect.
-
- "idex=reset"          : reset interface after probe
-
- "idex=ata66"          : informs the interface that it has an 80c cable
-                         for chipsets that are ATA-66 capable, but the
-                         ability to bit test for detection is currently
-                         unknown.
-
- "ide=doubler"         : probe/support IDE doublers on Amiga
-
-There may be more options than shown -- use the source, Luke!
-
-Everything else is rejected with a "BAD OPTION" message.
-
 For legacy IDE VLB host drivers (ali14xx/dtc2278/ht6560b/qd65xx/umc8672)
 you need to explicitly enable probing by using "probe" kernel parameter,
 i.e. to enable probing for ALI M14xx chipsets (ali14xx host driver) use:
@@ -251,6 +197,33 @@ are detected automatically).
 You also need to use "probe" kernel parameter for ide-4drives driver
 (support for IDE generic chipset with four drives on one port).
 
+To enable support for IDE doublers on Amiga use "doubler" kernel parameter
+for gayle host driver (i.e. "gayle.doubler" if the driver is built-in).
+
+To force ignoring cable detection (this should be needed only if you're using
+short 40-wires cable which cannot be automatically detected - if this is not
+a case please report it as a bug instead) use "ignore_cable" kernel parameter:
+
+* "ide_core.ignore_cable=[interface_number]" boot option if IDE is built-in
+  (i.e. "ide_core.ignore_cable=1" to force ignoring cable for "ide1")
+
+* "ignore_cable=[interface_number]" module parameter (for ide_core module)
+  if IDE is compiled as module
+
+Other kernel parameters for ide_core are:
+
+* "nodma=[interface_number.device_number]" to disallow DMA for a device
+
+* "noflush=[interface_number.device_number]" to disable flush requests
+
+* "noprobe=[interface_number.device_number]" to skip probing
+
+* "nowerr=[interface_number.device_number]" to ignore the WRERR_STAT bit
+
+* "cdrom=[interface_number.device_number]" to force device as a CD-ROM
+
+* "chs=[interface_number.device_number]" to force device as a disk (using CHS)
+
 ================================================================================
 
 Some Terminology
index c18363b..240ce7a 100644 (file)
@@ -183,6 +183,8 @@ Code        Seq#    Include File            Comments
 0xAC   00-1F   linux/raw.h
 0xAD   00      Netfilter device        in development:
                                        <mailto:rusty@rustcorp.com.au>  
+0xAE   all     linux/kvm.h             Kernel-based Virtual Machine
+                                       <mailto:kvm-devel@lists.sourceforge.net>
 0xB0   all     RATIO devices           in development:
                                        <mailto:vgo@ratio.de>
 0xB1   00-1F   PPPoX                   <mailto:mostrows@styx.uwaterloo.ca>
index bf6303e..e5f3d91 100644 (file)
@@ -772,10 +772,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        Format: ide=nodma or ide=doubler
                        See Documentation/ide/ide.txt.
 
-       ide?=           [HW] (E)IDE subsystem
-                       Format: ide?=ata66 or chipset specific parameters.
-                       See Documentation/ide/ide.txt.
-
        idebus=         [HW] (E)IDE subsystem - VLB/PCI bus speed
                        See Documentation/ide/ide.txt.
 
index be89f39..6877e71 100644 (file)
@@ -37,6 +37,11 @@ registration function such as register_kprobe() specifies where
 the probe is to be inserted and what handler is to be called when
 the probe is hit.
 
+There are also register_/unregister_*probes() functions for batch
+registration/unregistration of a group of *probes. These functions
+can speed up unregistration process when you have to unregister
+a lot of probes at once.
+
 The next three subsections explain how the different types of
 probes work.  They explain certain things that you'll need to
 know in order to make the best use of Kprobes -- e.g., the
@@ -190,10 +195,11 @@ code mapping.
 4. API Reference
 
 The Kprobes API includes a "register" function and an "unregister"
-function for each type of probe.  Here are terse, mini-man-page
-specifications for these functions and the associated probe handlers
-that you'll write.  See the files in the samples/kprobes/ sub-directory
-for examples.
+function for each type of probe. The API also includes "register_*probes"
+and "unregister_*probes" functions for (un)registering arrays of probes.
+Here are terse, mini-man-page specifications for these functions and
+the associated probe handlers that you'll write. See the files in the
+samples/kprobes/ sub-directory for examples.
 
 4.1 register_kprobe
 
@@ -319,6 +325,43 @@ void unregister_kretprobe(struct kretprobe *rp);
 Removes the specified probe.  The unregister function can be called
 at any time after the probe has been registered.
 
+NOTE:
+If the functions find an incorrect probe (ex. an unregistered probe),
+they clear the addr field of the probe.
+
+4.5 register_*probes
+
+#include <linux/kprobes.h>
+int register_kprobes(struct kprobe **kps, int num);
+int register_kretprobes(struct kretprobe **rps, int num);
+int register_jprobes(struct jprobe **jps, int num);
+
+Registers each of the num probes in the specified array.  If any
+error occurs during registration, all probes in the array, up to
+the bad probe, are safely unregistered before the register_*probes
+function returns.
+- kps/rps/jps: an array of pointers to *probe data structures
+- num: the number of the array entries.
+
+NOTE:
+You have to allocate(or define) an array of pointers and set all
+of the array entries before using these functions.
+
+4.6 unregister_*probes
+
+#include <linux/kprobes.h>
+void unregister_kprobes(struct kprobe **kps, int num);
+void unregister_kretprobes(struct kretprobe **rps, int num);
+void unregister_jprobes(struct jprobe **jps, int num);
+
+Removes each of the num probes in the specified array at once.
+
+NOTE:
+If the functions find some incorrect probes (ex. unregistered
+probes) in the specified array, they clear the addr field of those
+incorrect probes. However, other probes in the array are
+unregistered correctly.
+
 5. Kprobes Features and Limitations
 
 Kprobes allows multiple probes at the same address.  Currently,
index 396cdd9..a8b4306 100644 (file)
@@ -450,3 +450,9 @@ These currently include
       there are upper and lower limits (32768, 16).  Default is 128.
   strip_cache_active (currently raid5 only)
       number of active entries in the stripe cache
+  preread_bypass_threshold (currently raid5 only)
+      number of times a stripe requiring preread will be bypassed by
+      a stripe that does not require preread.  For fairness defaults
+      to 1.  Setting this to 0 disables bypass accounting and
+      requires preread stripes to wait until all full-width stripe-
+      writes are complete.  Valid values are 0 to stripe_cache_size.
index cf89e8c..1d2a772 100644 (file)
@@ -2836,6 +2836,39 @@ platforms are moved over to use the flattened-device-tree model.
                   big-endian;
           };
 
+    r) Freescale Display Interface Unit
+
+    The Freescale DIU is a LCD controller, with proper hardware, it can also
+    drive DVI monitors.
+
+    Required properties:
+    - compatible : should be "fsl-diu".
+    - reg : should contain at least address and length of the DIU register
+      set.
+    - Interrupts : one DIU interrupt should be describe here.
+
+    Example (MPC8610HPCD)
+       display@2c000 {
+               compatible = "fsl,diu";
+               reg = <0x2c000 100>;
+               interrupts = <72 2>;
+               interrupt-parent = <&mpic>;
+       };
+
+    s) Freescale on board FPGA
+
+    This is the memory-mapped registers for on board FPGA.
+
+    Required properities:
+    - compatible : should be "fsl,fpga-pixis".
+    - reg : should contain the address and the lenght of the FPPGA register
+      set.
+
+    Example (MPC8610HPCD)
+       board-control@e8000000 {
+               compatible = "fsl,fpga-pixis";
+               reg = <0xe8000000 32>;
+       };
 
 VII - Marvell Discovery mv64[345]6x System Controller chips
 ===========================================================
diff --git a/Documentation/powerpc/kvm_440.txt b/Documentation/powerpc/kvm_440.txt
new file mode 100644 (file)
index 0000000..c02a003
--- /dev/null
@@ -0,0 +1,41 @@
+Hollis Blanchard <hollisb@us.ibm.com>
+15 Apr 2008
+
+Various notes on the implementation of KVM for PowerPC 440:
+
+To enforce isolation, host userspace, guest kernel, and guest userspace all
+run at user privilege level. Only the host kernel runs in supervisor mode.
+Executing privileged instructions in the guest traps into KVM (in the host
+kernel), where we decode and emulate them. Through this technique, unmodified
+440 Linux kernels can be run (slowly) as guests. Future performance work will
+focus on reducing the overhead and frequency of these traps.
+
+The usual code flow is started from userspace invoking an "run" ioctl, which
+causes KVM to switch into guest context. We use IVPR to hijack the host
+interrupt vectors while running the guest, which allows us to direct all
+interrupts to kvmppc_handle_interrupt(). At this point, we could either
+- handle the interrupt completely (e.g. emulate "mtspr SPRG0"), or
+- let the host interrupt handler run (e.g. when the decrementer fires), or
+- return to host userspace (e.g. when the guest performs device MMIO)
+
+Address spaces: We take advantage of the fact that Linux doesn't use the AS=1
+address space (in host or guest), which gives us virtual address space to use
+for guest mappings. While the guest is running, the host kernel remains mapped
+in AS=0, but the guest can only use AS=1 mappings.
+
+TLB entries: The TLB entries covering the host linear mapping remain
+present while running the guest. This reduces the overhead of lightweight
+exits, which are handled by KVM running in the host kernel. We keep three
+copies of the TLB:
+ - guest TLB: contents of the TLB as the guest sees it
+ - shadow TLB: the TLB that is actually in hardware while guest is running
+ - host TLB: to restore TLB state when context switching guest -> host
+When a TLB miss occurs because a mapping was not present in the shadow TLB,
+but was present in the guest TLB, KVM handles the fault without invoking the
+guest. Large guest pages are backed by multiple 4KB shadow pages through this
+mechanism.
+
+IO: MMIO and DCR accesses are emulated by userspace. We use virtio for network
+and block IO, so those drivers must be enabled in the guest. It's possible
+that some qemu device emulation (e.g. e1000 or rtl8139) may also work with
+little effort.
diff --git a/Documentation/s390/kvm.txt b/Documentation/s390/kvm.txt
new file mode 100644 (file)
index 0000000..6f5ceb0
--- /dev/null
@@ -0,0 +1,125 @@
+*** BIG FAT WARNING ***
+The kvm module is currently in EXPERIMENTAL state for s390. This means that
+the interface to the module is not yet considered to remain stable. Thus, be
+prepared that we keep breaking your userspace application and guest
+compatibility over and over again until we feel happy with the result. Make sure
+your guest kernel, your host kernel, and your userspace launcher are in a
+consistent state.
+
+This Documentation describes the unique ioctl calls to /dev/kvm, the resulting
+kvm-vm file descriptors, and the kvm-vcpu file descriptors that differ from x86.
+
+1. ioctl calls to /dev/kvm
+KVM does support the following ioctls on s390 that are common with other
+architectures and do behave the same:
+KVM_GET_API_VERSION
+KVM_CREATE_VM          (*) see note
+KVM_CHECK_EXTENSION
+KVM_GET_VCPU_MMAP_SIZE
+
+Notes:
+* KVM_CREATE_VM may fail on s390, if the calling process has multiple
+threads and has not called KVM_S390_ENABLE_SIE before.
+
+In addition, on s390 the following architecture specific ioctls are supported:
+ioctl:         KVM_S390_ENABLE_SIE
+args:          none
+see also:      include/linux/kvm.h
+This call causes the kernel to switch on PGSTE in the user page table. This
+operation is needed in order to run a virtual machine, and it requires the
+calling process to be single-threaded. Note that the first call to KVM_CREATE_VM
+will implicitly try to switch on PGSTE if the user process has not called
+KVM_S390_ENABLE_SIE before. User processes that want to launch multiple threads
+before creating a virtual machine have to call KVM_S390_ENABLE_SIE, or will
+observe an error calling KVM_CREATE_VM. Switching on PGSTE is a one-time
+operation, is not reversible, and will persist over the entire lifetime of
+the calling process. It does not have any user-visible effect other than a small
+performance penalty.
+
+2. ioctl calls to the kvm-vm file descriptor
+KVM does support the following ioctls on s390 that are common with other
+architectures and do behave the same:
+KVM_CREATE_VCPU
+KVM_SET_USER_MEMORY_REGION      (*) see note
+KVM_GET_DIRTY_LOG              (**) see note
+
+Notes:
+*  kvm does only allow exactly one memory slot on s390, which has to start
+   at guest absolute address zero and at a user address that is aligned on any
+   page boundary. This hardware "limitation" allows us to have a few unique
+   optimizations. The memory slot doesn't have to be filled
+   with memory actually, it may contain sparse holes. That said, with different
+   user memory layout this does still allow a large flexibility when
+   doing the guest memory setup.
+** KVM_GET_DIRTY_LOG doesn't work properly yet. The user will receive an empty
+log. This ioctl call is only needed for guest migration, and we intend to
+implement this one in the future.
+
+In addition, on s390 the following architecture specific ioctls for the kvm-vm
+file descriptor are supported:
+ioctl:         KVM_S390_INTERRUPT
+args:          struct kvm_s390_interrupt *
+see also:      include/linux/kvm.h
+This ioctl is used to submit a floating interrupt for a virtual machine.
+Floating interrupts may be delivered to any virtual cpu in the configuration.
+Only some interrupt types defined in include/linux/kvm.h make sense when
+submitted as floating interrupts. The following interrupts are not considered
+to be useful as floating interrupts, and a call to inject them will result in
+-EINVAL error code: program interrupts and interprocessor signals. Valid
+floating interrupts are:
+KVM_S390_INT_VIRTIO
+KVM_S390_INT_SERVICE
+
+3. ioctl calls to the kvm-vcpu file descriptor
+KVM does support the following ioctls on s390 that are common with other
+architectures and do behave the same:
+KVM_RUN
+KVM_GET_REGS
+KVM_SET_REGS
+KVM_GET_SREGS
+KVM_SET_SREGS
+KVM_GET_FPU
+KVM_SET_FPU
+
+In addition, on s390 the following architecture specific ioctls for the
+kvm-vcpu file descriptor are supported:
+ioctl:         KVM_S390_INTERRUPT
+args:          struct kvm_s390_interrupt *
+see also:      include/linux/kvm.h
+This ioctl is used to submit an interrupt for a specific virtual cpu.
+Only some interrupt types defined in include/linux/kvm.h make sense when
+submitted for a specific cpu. The following interrupts are not considered
+to be useful, and a call to inject them will result in -EINVAL error code:
+service processor calls and virtio interrupts. Valid interrupt types are:
+KVM_S390_PROGRAM_INT
+KVM_S390_SIGP_STOP
+KVM_S390_RESTART
+KVM_S390_SIGP_SET_PREFIX
+KVM_S390_INT_EMERGENCY
+
+ioctl:         KVM_S390_STORE_STATUS
+args:          unsigned long
+see also:      include/linux/kvm.h
+This ioctl stores the state of the cpu at the guest real address given as
+argument, unless one of the following values defined in include/linux/kvm.h
+is given as arguement:
+KVM_S390_STORE_STATUS_NOADDR - the CPU stores its status to the save area in
+absolute lowcore as defined by the principles of operation
+KVM_S390_STORE_STATUS_PREFIXED - the CPU stores its status to the save area in
+its prefix page just like the dump tool that comes with zipl. This is useful
+to create a system dump for use with lkcdutils or crash.
+
+ioctl:         KVM_S390_SET_INITIAL_PSW
+args:          struct kvm_s390_psw *
+see also:      include/linux/kvm.h
+This ioctl can be used to set the processor status word (psw) of a stopped cpu
+prior to running it with KVM_RUN. Note that this call is not required to modify
+the psw during sie intercepts that fall back to userspace because struct kvm_run
+does contain the psw, and this value is evaluated during reentry of KVM_RUN
+after the intercept exit was recognized.
+
+ioctl:         KVM_S390_INITIAL_RESET
+args:          none
+see also:      include/linux/kvm.h
+This ioctl can be used to perform an initial cpu reset as defined by the
+principles of operation. The target cpu has to be in stopped state.
index 5c8e1b9..ed2da5e 100644 (file)
@@ -126,8 +126,8 @@ NOTES:
 FULL DUPLEX CHARACTER DEVICE API
 ================================
 
-See the sample program below for one example showing the use of the full
-duplex programming interface.  (Although it doesn't perform a full duplex
+See the spidev_fdx.c sample program for one example showing the use of the
+full duplex programming interface.  (Although it doesn't perform a full duplex
 transfer.)  The model is the same as that used in the kernel spi_sync()
 request; the individual transfers offer the same capabilities as are
 available to kernel drivers (except that it's not asynchronous).
@@ -141,167 +141,3 @@ and bitrate for each transfer segment.)
 
 To make a full duplex request, provide both rx_buf and tx_buf for the
 same transfer.  It's even OK if those are the same buffer.
-
-
-SAMPLE PROGRAM
-==============
-
---------------------------------       CUT HERE
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <linux/types.h>
-#include <linux/spi/spidev.h>
-
-
-static int verbose;
-
-static void do_read(int fd, int len)
-{
-       unsigned char   buf[32], *bp;
-       int             status;
-
-       /* read at least 2 bytes, no more than 32 */
-       if (len < 2)
-               len = 2;
-       else if (len > sizeof(buf))
-               len = sizeof(buf);
-       memset(buf, 0, sizeof buf);
-
-       status = read(fd, buf, len);
-       if (status < 0) {
-               perror("read");
-               return;
-       }
-       if (status != len) {
-               fprintf(stderr, "short read\n");
-               return;
-       }
-
-       printf("read(%2d, %2d): %02x %02x,", len, status,
-               buf[0], buf[1]);
-       status -= 2;
-       bp = buf + 2;
-       while (status-- > 0)
-               printf(" %02x", *bp++);
-       printf("\n");
-}
-
-static void do_msg(int fd, int len)
-{
-       struct spi_ioc_transfer xfer[2];
-       unsigned char           buf[32], *bp;
-       int                     status;
-
-       memset(xfer, 0, sizeof xfer);
-       memset(buf, 0, sizeof buf);
-
-       if (len > sizeof buf)
-               len = sizeof buf;
-
-       buf[0] = 0xaa;
-       xfer[0].tx_buf = (__u64) buf;
-       xfer[0].len = 1;
-
-       xfer[1].rx_buf = (__u64) buf;
-       xfer[1].len = len;
-
-       status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
-       if (status < 0) {
-               perror("SPI_IOC_MESSAGE");
-               return;
-       }
-
-       printf("response(%2d, %2d): ", len, status);
-       for (bp = buf; len; len--)
-               printf(" %02x", *bp++);
-       printf("\n");
-}
-
-static void dumpstat(const char *name, int fd)
-{
-       __u8    mode, lsb, bits;
-       __u32   speed;
-
-       if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) {
-               perror("SPI rd_mode");
-               return;
-       }
-       if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
-               perror("SPI rd_lsb_fist");
-               return;
-       }
-       if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
-               perror("SPI bits_per_word");
-               return;
-       }
-       if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
-               perror("SPI max_speed_hz");
-               return;
-       }
-
-       printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
-               name, mode, bits, lsb ? "(lsb first) " : "", speed);
-}
-
-int main(int argc, char **argv)
-{
-       int             c;
-       int             readcount = 0;
-       int             msglen = 0;
-       int             fd;
-       const char      *name;
-
-       while ((c = getopt(argc, argv, "hm:r:v")) != EOF) {
-               switch (c) {
-               case 'm':
-                       msglen = atoi(optarg);
-                       if (msglen < 0)
-                               goto usage;
-                       continue;
-               case 'r':
-                       readcount = atoi(optarg);
-                       if (readcount < 0)
-                               goto usage;
-                       continue;
-               case 'v':
-                       verbose++;
-                       continue;
-               case 'h':
-               case '?':
-usage:
-                       fprintf(stderr,
-                               "usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n",
-                               argv[0]);
-                       return 1;
-               }
-       }
-
-       if ((optind + 1) != argc)
-               goto usage;
-       name = argv[optind];
-
-       fd = open(name, O_RDWR);
-       if (fd < 0) {
-               perror("open");
-               return 1;
-       }
-
-       dumpstat(name, fd);
-
-       if (msglen)
-               do_msg(fd, msglen);
-
-       if (readcount)
-               do_read(fd, readcount);
-
-       close(fd);
-       return 0;
-}
diff --git a/Documentation/spi/spidev_fdx.c b/Documentation/spi/spidev_fdx.c
new file mode 100644 (file)
index 0000000..fc354f7
--- /dev/null
@@ -0,0 +1,158 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <linux/types.h>
+#include <linux/spi/spidev.h>
+
+
+static int verbose;
+
+static void do_read(int fd, int len)
+{
+       unsigned char   buf[32], *bp;
+       int             status;
+
+       /* read at least 2 bytes, no more than 32 */
+       if (len < 2)
+               len = 2;
+       else if (len > sizeof(buf))
+               len = sizeof(buf);
+       memset(buf, 0, sizeof buf);
+
+       status = read(fd, buf, len);
+       if (status < 0) {
+               perror("read");
+               return;
+       }
+       if (status != len) {
+               fprintf(stderr, "short read\n");
+               return;
+       }
+
+       printf("read(%2d, %2d): %02x %02x,", len, status,
+               buf[0], buf[1]);
+       status -= 2;
+       bp = buf + 2;
+       while (status-- > 0)
+               printf(" %02x", *bp++);
+       printf("\n");
+}
+
+static void do_msg(int fd, int len)
+{
+       struct spi_ioc_transfer xfer[2];
+       unsigned char           buf[32], *bp;
+       int                     status;
+
+       memset(xfer, 0, sizeof xfer);
+       memset(buf, 0, sizeof buf);
+
+       if (len > sizeof buf)
+               len = sizeof buf;
+
+       buf[0] = 0xaa;
+       xfer[0].tx_buf = (__u64) buf;
+       xfer[0].len = 1;
+
+       xfer[1].rx_buf = (__u64) buf;
+       xfer[1].len = len;
+
+       status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
+       if (status < 0) {
+               perror("SPI_IOC_MESSAGE");
+               return;
+       }
+
+       printf("response(%2d, %2d): ", len, status);
+       for (bp = buf; len; len--)
+               printf(" %02x", *bp++);
+       printf("\n");
+}
+
+static void dumpstat(const char *name, int fd)
+{
+       __u8    mode, lsb, bits;
+       __u32   speed;
+
+       if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) {
+               perror("SPI rd_mode");
+               return;
+       }
+       if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
+               perror("SPI rd_lsb_fist");
+               return;
+       }
+       if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
+               perror("SPI bits_per_word");
+               return;
+       }
+       if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
+               perror("SPI max_speed_hz");
+               return;
+       }
+
+       printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
+               name, mode, bits, lsb ? "(lsb first) " : "", speed);
+}
+
+int main(int argc, char **argv)
+{
+       int             c;
+       int             readcount = 0;
+       int             msglen = 0;
+       int             fd;
+       const char      *name;
+
+       while ((c = getopt(argc, argv, "hm:r:v")) != EOF) {
+               switch (c) {
+               case 'm':
+                       msglen = atoi(optarg);
+                       if (msglen < 0)
+                               goto usage;
+                       continue;
+               case 'r':
+                       readcount = atoi(optarg);
+                       if (readcount < 0)
+                               goto usage;
+                       continue;
+               case 'v':
+                       verbose++;
+                       continue;
+               case 'h':
+               case '?':
+usage:
+                       fprintf(stderr,
+                               "usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n",
+                               argv[0]);
+                       return 1;
+               }
+       }
+
+       if ((optind + 1) != argc)
+               goto usage;
+       name = argv[optind];
+
+       fd = open(name, O_RDWR);
+       if (fd < 0) {
+               perror("open");
+               return 1;
+       }
+
+       dumpstat(name, fd);
+
+       if (msglen)
+               do_msg(fd, msglen);
+
+       if (readcount)
+               do_read(fd, readcount);
+
+       close(fd);
+       return 0;
+}
index dd49864..bad16d3 100644 (file)
@@ -135,77 +135,58 @@ most general to most specific:
 
 Components of Memory Policies
 
-    A Linux memory policy is a tuple consisting of a "mode" and an optional set
-    of nodes.  The mode determine the behavior of the policy, while the
-    optional set of nodes can be viewed as the arguments to the behavior.
+    A Linux memory policy consists of a "mode", optional mode flags, and an
+    optional set of nodes.  The mode determines the behavior of the policy,
+    the optional mode flags determine the behavior of the mode, and the
+    optional set of nodes can be viewed as the arguments to the policy
+    behavior.
 
    Internally, memory policies are implemented by a reference counted
    structure, struct mempolicy.  Details of this structure will be discussed
    in context, below, as required to explain the behavior.
 
-       Note:  in some functions AND in the struct mempolicy itself, the mode
-       is called "policy".  However, to avoid confusion with the policy tuple,
-       this document will continue to use the term "mode".
-
    Linux memory policy supports the following 4 behavioral modes:
 
-       Default Mode--MPOL_DEFAULT:  The behavior specified by this mode is
-       context or scope dependent.
-
-           As mentioned in the Policy Scope section above, during normal
-           system operation, the System Default Policy is hard coded to
-           contain the Default mode.
-
-           In this context, default mode means "local" allocation--that is
-           attempt to allocate the page from the node associated with the cpu
-           where the fault occurs.  If the "local" node has no memory, or the
-           node's memory can be exhausted [no free pages available], local
-           allocation will "fallback to"--attempt to allocate pages from--
-           "nearby" nodes, in order of increasing "distance".
+       Default Mode--MPOL_DEFAULT:  This mode is only used in the memory
+       policy APIs.  Internally, MPOL_DEFAULT is converted to the NULL
+       memory policy in all policy scopes.  Any existing non-default policy
+       will simply be removed when MPOL_DEFAULT is specified.  As a result,
+       MPOL_DEFAULT means "fall back to the next most specific policy scope."
 
-               Implementation detail -- subject to change:  "Fallback" uses
-               a per node list of sibling nodes--called zonelists--built at
-               boot time, or when nodes or memory are added or removed from
-               the system [memory hotplug].  These per node zonelist are
-               constructed with nodes in order of increasing distance based
-               on information provided by the platform firmware.
+           For example, a NULL or default task policy will fall back to the
+           system default policy.  A NULL or default vma policy will fall
+           back to the task policy.
 
-           When a task/process policy or a shared policy contains the Default
-           mode, this also means "local allocation", as described above.
+           When specified in one of the memory policy APIs, the Default mode
+           does not use the optional set of nodes.
 
-           In the context of a VMA, Default mode means "fall back to task
-           policy"--which may or may not specify Default mode.  Thus, Default
-           mode can not be counted on to mean local allocation when used
-           on a non-shared region of the address space.  However, see
-           MPOL_PREFERRED below.
-
-           The Default mode does not use the optional set of nodes.
+           It is an error for the set of nodes specified for this policy to
+           be non-empty.
 
        MPOL_BIND:  This mode specifies that memory must come from the
-       set of nodes specified by the policy.
-
-           The memory policy APIs do not specify an order in which the nodes
-           will be searched.  However, unlike "local allocation", the Bind
-           policy does not consider the distance between the nodes.  Rather,
-           allocations will fallback to the nodes specified by the policy in
-           order of numeric node id.  Like everything in Linux, this is subject
-           to change.
+       set of nodes specified by the policy.  Memory will be allocated from
+       the node in the set with sufficient free memory that is closest to
+       the node where the allocation takes place.
 
        MPOL_PREFERRED:  This mode specifies that the allocation should be
        attempted from the single node specified in the policy.  If that
-       allocation fails, the kernel will search other nodes, exactly as
-       it would for a local allocation that started at the preferred node
-       in increasing distance from the preferred node.  "Local" allocation
-       policy can be viewed as a Preferred policy that starts at the node
+       allocation fails, the kernel will search other nodes, in order of
+       increasing distance from the preferred node based on information
+       provided by the platform firmware.
        containing the cpu where the allocation takes place.
 
            Internally, the Preferred policy uses a single node--the
-           preferred_node member of struct mempolicy.  A "distinguished
-           value of this preferred_node, currently '-1', is interpreted
-           as "the node containing the cpu where the allocation takes
-           place"--local allocation.  This is the way to specify
-           local allocation for a specific range of addresses--i.e. for
-           VMA policies.
+           preferred_node member of struct mempolicy.  When the internal
+           mode flag MPOL_F_LOCAL is set, the preferred_node is ignored and
+           the policy is interpreted as local allocation.  "Local" allocation
+           policy can be viewed as a Preferred policy that starts at the node
+           containing the cpu where the allocation takes place.
+
+           It is possible for the user to specify that local allocation is
+           always preferred by passing an empty nodemask with this mode.
+           If an empty nodemask is passed, the policy cannot use the
+           MPOL_F_STATIC_NODES or MPOL_F_RELATIVE_NODES flags described
+           below.
 
        MPOL_INTERLEAVED:  This mode specifies that page allocations be
        interleaved, on a page granularity, across the nodes specified in
@@ -231,6 +212,154 @@ Components of Memory Policies
            the temporary interleaved system default policy works in this
            mode.
 
+   Linux memory policy supports the following optional mode flags:
+
+       MPOL_F_STATIC_NODES:  This flag specifies that the nodemask passed by
+       the user should not be remapped if the task or VMA's set of allowed
+       nodes changes after the memory policy has been defined.
+
+           Without this flag, anytime a mempolicy is rebound because of a
+           change in the set of allowed nodes, the node (Preferred) or
+           nodemask (Bind, Interleave) is remapped to the new set of
+           allowed nodes.  This may result in nodes being used that were
+           previously undesired.
+
+           With this flag, if the user-specified nodes overlap with the
+           nodes allowed by the task's cpuset, then the memory policy is
+           applied to their intersection.  If the two sets of nodes do not
+           overlap, the Default policy is used.
+
+           For example, consider a task that is attached to a cpuset with
+           mems 1-3 that sets an Interleave policy over the same set.  If
+           the cpuset's mems change to 3-5, the Interleave will now occur
+           over nodes 3, 4, and 5.  With this flag, however, since only node
+           3 is allowed from the user's nodemask, the "interleave" only
+           occurs over that node.  If no nodes from the user's nodemask are
+           now allowed, the Default behavior is used.
+
+           MPOL_F_STATIC_NODES cannot be combined with the
+           MPOL_F_RELATIVE_NODES flag.  It also cannot be used for
+           MPOL_PREFERRED policies that were created with an empty nodemask
+           (local allocation).
+
+       MPOL_F_RELATIVE_NODES:  This flag specifies that the nodemask passed
+       by the user will be mapped relative to the set of the task or VMA's
+       set of allowed nodes.  The kernel stores the user-passed nodemask,
+       and if the allowed nodes changes, then that original nodemask will
+       be remapped relative to the new set of allowed nodes.
+
+           Without this flag (and without MPOL_F_STATIC_NODES), anytime a
+           mempolicy is rebound because of a change in the set of allowed
+           nodes, the node (Preferred) or nodemask (Bind, Interleave) is
+           remapped to the new set of allowed nodes.  That remap may not
+           preserve the relative nature of the user's passed nodemask to its
+           set of allowed nodes upon successive rebinds: a nodemask of
+           1,3,5 may be remapped to 7-9 and then to 1-3 if the set of
+           allowed nodes is restored to its original state.
+
+           With this flag, the remap is done so that the node numbers from
+           the user's passed nodemask are relative to the set of allowed
+           nodes.  In other words, if nodes 0, 2, and 4 are set in the user's
+           nodemask, the policy will be effected over the first (and in the
+           Bind or Interleave case, the third and fifth) nodes in the set of
+           allowed nodes.  The nodemask passed by the user represents nodes
+           relative to task or VMA's set of allowed nodes.
+
+           If the user's nodemask includes nodes that are outside the range
+           of the new set of allowed nodes (for example, node 5 is set in
+           the user's nodemask when the set of allowed nodes is only 0-3),
+           then the remap wraps around to the beginning of the nodemask and,
+           if not already set, sets the node in the mempolicy nodemask.
+
+           For example, consider a task that is attached to a cpuset with
+           mems 2-5 that sets an Interleave policy over the same set with
+           MPOL_F_RELATIVE_NODES.  If the cpuset's mems change to 3-7, the
+           interleave now occurs over nodes 3,5-6.  If the cpuset's mems
+           then change to 0,2-3,5, then the interleave occurs over nodes
+           0,3,5.
+
+           Thanks to the consistent remapping, applications preparing
+           nodemasks to specify memory policies using this flag should
+           disregard their current, actual cpuset imposed memory placement
+           and prepare the nodemask as if they were always located on
+           memory nodes 0 to N-1, where N is the number of memory nodes the
+           policy is intended to manage.  Let the kernel then remap to the
+           set of memory nodes allowed by the task's cpuset, as that may
+           change over time.
+
+           MPOL_F_RELATIVE_NODES cannot be combined with the
+           MPOL_F_STATIC_NODES flag.  It also cannot be used for
+           MPOL_PREFERRED policies that were created with an empty nodemask
+           (local allocation).
+
+MEMORY POLICY REFERENCE COUNTING
+
+To resolve use/free races, struct mempolicy contains an atomic reference
+count field.  Internal interfaces, mpol_get()/mpol_put() increment and
+decrement this reference count, respectively.  mpol_put() will only free
+the structure back to the mempolicy kmem cache when the reference count
+goes to zero.
+
+When a new memory policy is allocated, it's reference count is initialized
+to '1', representing the reference held by the task that is installing the
+new policy.  When a pointer to a memory policy structure is stored in another
+structure, another reference is added, as the task's reference will be dropped
+on completion of the policy installation.
+
+During run-time "usage" of the policy, we attempt to minimize atomic operations
+on the reference count, as this can lead to cache lines bouncing between cpus
+and NUMA nodes.  "Usage" here means one of the following:
+
+1) querying of the policy, either by the task itself [using the get_mempolicy()
+   API discussed below] or by another task using the /proc/<pid>/numa_maps
+   interface.
+
+2) examination of the policy to determine the policy mode and associated node
+   or node lists, if any, for page allocation.  This is considered a "hot
+   path".  Note that for MPOL_BIND, the "usage" extends across the entire
+   allocation process, which may sleep during page reclaimation, because the
+   BIND policy nodemask is used, by reference, to filter ineligible nodes.
+
+We can avoid taking an extra reference during the usages listed above as
+follows:
+
+1) we never need to get/free the system default policy as this is never
+   changed nor freed, once the system is up and running.
+
+2) for querying the policy, we do not need to take an extra reference on the
+   target task's task policy nor vma policies because we always acquire the
+   task's mm's mmap_sem for read during the query.  The set_mempolicy() and
+   mbind() APIs [see below] always acquire the mmap_sem for write when
+   installing or replacing task or vma policies.  Thus, there is no possibility
+   of a task or thread freeing a policy while another task or thread is
+   querying it.
+
+3) Page allocation usage of task or vma policy occurs in the fault path where
+   we hold them mmap_sem for read.  Again, because replacing the task or vma
+   policy requires that the mmap_sem be held for write, the policy can't be
+   freed out from under us while we're using it for page allocation.
+
+4) Shared policies require special consideration.  One task can replace a
+   shared memory policy while another task, with a distinct mmap_sem, is
+   querying or allocating a page based on the policy.  To resolve this
+   potential race, the shared policy infrastructure adds an extra reference
+   to the shared policy during lookup while holding a spin lock on the shared
+   policy management structure.  This requires that we drop this extra
+   reference when we're finished "using" the policy.  We must drop the
+   extra reference on shared policies in the same query/allocation paths
+   used for non-shared policies.  For this reason, shared policies are marked
+   as such, and the extra reference is dropped "conditionally"--i.e., only
+   for shared policies.
+
+   Because of this extra reference counting, and because we must lookup
+   shared policies in a tree structure under spinlock, shared policies are
+   more expensive to use in the page allocation path.  This is expecially
+   true for shared policies on shared memory regions shared by tasks running
+   on different NUMA nodes.  This extra overhead can be avoided by always
+   falling back to task or system default policy for shared memory regions,
+   or by prefaulting the entire shared memory region into memory and locking
+   it down.  However, this might not be appropriate for all applications.
+
 MEMORY POLICY APIs
 
 Linux supports 3 system calls for controlling memory policy.  These APIS
@@ -251,7 +380,9 @@ Set [Task] Memory Policy:
        Set's the calling task's "task/process memory policy" to mode
        specified by the 'mode' argument and the set of nodes defined
        by 'nmask'.  'nmask' points to a bit mask of node ids containing
-       at least 'maxnode' ids.
+       at least 'maxnode' ids.  Optional mode flags may be passed by
+       combining the 'mode' argument with the flag (for example:
+       MPOL_INTERLEAVE | MPOL_F_STATIC_NODES).
 
        See the set_mempolicy(2) man page for more details
 
@@ -303,29 +434,19 @@ MEMORY POLICIES AND CPUSETS
 Memory policies work within cpusets as described above.  For memory policies
 that require a node or set of nodes, the nodes are restricted to the set of
 nodes whose memories are allowed by the cpuset constraints.  If the nodemask
-specified for the policy contains nodes that are not allowed by the cpuset, or
-the intersection of the set of nodes specified for the policy and the set of
-nodes with memory is the empty set, the policy is considered invalid
-and cannot be installed.
-
-The interaction of memory policies and cpusets can be problematic for a
-couple of reasons:
-
-1) the memory policy APIs take physical node id's as arguments.  As mentioned
-   above, it is illegal to specify nodes that are not allowed in the cpuset.
-   The application must query the allowed nodes using the get_mempolicy()
-   API with the MPOL_F_MEMS_ALLOWED flag to determine the allowed nodes and
-   restrict itself to those nodes.  However, the resources available to a
-   cpuset can be changed by the system administrator, or a workload manager
-   application, at any time.  So, a task may still get errors attempting to
-   specify policy nodes, and must query the allowed memories again.
-
-2) when tasks in two cpusets share access to a memory region, such as shared
-   memory segments created by shmget() of mmap() with the MAP_ANONYMOUS and
-   MAP_SHARED flags, and any of the tasks install shared policy on the region,
-   only nodes whose memories are allowed in both cpusets may be used in the
-   policies.  Obtaining this information requires "stepping outside" the
-   memory policy APIs to use the cpuset information and requires that one
-   know in what cpusets other task might be attaching to the shared region.
-   Furthermore, if the cpusets' allowed memory sets are disjoint, "local"
-   allocation is the only valid policy.
+specified for the policy contains nodes that are not allowed by the cpuset and
+MPOL_F_RELATIVE_NODES is not used, the intersection of the set of nodes
+specified for the policy and the set of nodes with memory is used.  If the
+result is the empty set, the policy is considered invalid and cannot be
+installed.  If MPOL_F_RELATIVE_NODES is used, the policy's nodes are mapped
+onto and folded into the task's set of allowed nodes as previously described.
+
+The interaction of memory policies and cpusets can be problematic when tasks
+in two cpusets share access to a memory region, such as shared memory segments
+created by shmget() of mmap() with the MAP_ANONYMOUS and MAP_SHARED flags, and
+any of the tasks install shared policy on the region, only nodes whose
+memories are allowed in both cpusets may be used in the policies.  Obtaining
+this information requires "stepping outside" the memory policy APIs to use the
+cpuset information and requires that one know in what cpusets other task might
+be attaching to the shared region.  Furthermore, if the cpusets' allowed
+memory sets are disjoint, "local" allocation is the only valid policy.
diff --git a/Kbuild b/Kbuild
index 1570d24..32f19c5 100644 (file)
--- a/Kbuild
+++ b/Kbuild
@@ -1,26 +1,61 @@
 #
 # Kbuild for top-level directory of the kernel
 # This file takes care of the following:
-# 1) Generate asm-offsets.h
-# 2) Check for missing system calls
+# 1) Generate bounds.h
+# 2) Generate asm-offsets.h (may need bounds.h)
+# 3) Check for missing system calls
 
 #####
-# 1) Generate asm-offsets.h
+# 1) Generate bounds.h
+
+bounds-file := include/linux/bounds.h
+
+always  := $(bounds-file)
+targets := $(bounds-file) kernel/bounds.s
+
+quiet_cmd_bounds = GEN     $@
+define cmd_bounds
+       (set -e; \
+        echo "#ifndef __LINUX_BOUNDS_H__"; \
+        echo "#define __LINUX_BOUNDS_H__"; \
+        echo "/*"; \
+        echo " * DO NOT MODIFY."; \
+        echo " *"; \
+        echo " * This file was generated by Kbuild"; \
+        echo " *"; \
+        echo " */"; \
+        echo ""; \
+        sed -ne $(sed-y) $<; \
+        echo ""; \
+        echo "#endif" ) > $@
+endef
+
+# We use internal kbuild rules to avoid the "is up to date" message from make
+kernel/bounds.s: kernel/bounds.c FORCE
+       $(Q)mkdir -p $(dir $@)
+       $(call if_changed_dep,cc_s_c)
+
+$(obj)/$(bounds-file): kernel/bounds.s Kbuild
+       $(Q)mkdir -p $(dir $@)
+       $(call cmd,bounds)
+
+#####
+# 2) Generate asm-offsets.h
 #
 
 offsets-file := include/asm-$(SRCARCH)/asm-offsets.h
 
-always  := $(offsets-file)
-targets := $(offsets-file)
+always  += $(offsets-file)
+targets += $(offsets-file)
 targets += arch/$(SRCARCH)/kernel/asm-offsets.s
-clean-files := $(addprefix $(objtree)/,$(targets))
+
 
 # Default sed regexp - multiline due to syntax constraints
 define sed-y
-       "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"
+       "/^->/{s:->#\(.*\):/* \1 */:; \
+       s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
+       s:->::; p;}"
 endef
-# Override default regexp for specific architectures
-sed-$(CONFIG_MIPS) := "/^@@@/{s/^@@@//; s/ \#.*\$$//; p;}"
 
 quiet_cmd_offsets = GEN     $@
 define cmd_offsets
@@ -40,7 +75,8 @@ define cmd_offsets
 endef
 
 # We use internal kbuild rules to avoid the "is up to date" message from make
-arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c FORCE
+arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \
+                                      $(obj)/$(bounds-file) FORCE
        $(Q)mkdir -p $(dir $@)
        $(call if_changed_dep,cc_s_c)
 
@@ -49,7 +85,7 @@ $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild
        $(call cmd,offsets)
 
 #####
-# 2) Check for missing system calls
+# 3) Check for missing system calls
 #
 
 quiet_cmd_syscalls = CALL    $<
@@ -58,3 +94,7 @@ quiet_cmd_syscalls = CALL    $<
 PHONY += missing-syscalls
 missing-syscalls: scripts/checksyscalls.sh FORCE
        $(call cmd,syscalls)
+
+# Delete all targets during make clean
+clean-files := $(addprefix $(objtree)/,$(targets))
+
index a942f38..c1dd1ae 100644 (file)
@@ -2329,6 +2329,13 @@ L:       kvm-devel@lists.sourceforge.net
 W:     kvm.sourceforge.net
 S:     Supported
 
+KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
+P:     Hollis Blanchard
+M:     hollisb@us.ibm.com
+L:     kvm-ppc-devel@lists.sourceforge.net
+W:     kvm.sourceforge.net
+S:     Supported
+
 KERNEL VIRTUAL MACHINE For Itanium(KVM/IA64)
 P:     Anthony Xu
 M:     anthony.xu@intel.com
@@ -2338,6 +2345,16 @@ L:       kvm-ia64-devel@lists.sourceforge.net
 W:     kvm.sourceforge.net
 S:     Supported
 
+KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
+P:     Carsten Otte
+M:     cotte@de.ibm.com
+P:     Christian Borntraeger
+M:     borntraeger@de.ibm.com
+M:     linux390@de.ibm.com
+L:     linux-s390@vger.kernel.org
+W:     http://www.ibm.com/developerworks/linux/linux390/
+S:     Supported
+
 KEXEC
 P:     Eric Biederman
 M:     ebiederm@xmission.com
index f10d2ed..b04f1fe 100644 (file)
@@ -994,7 +994,7 @@ marvel_agp_configure(alpha_agp_info *agp)
                 * rate, but warn the user.
                 */
                printk("%s: unknown PLL setting RNGB=%lx (PLL6_CTL=%016lx)\n",
-                      __FUNCTION__, IO7_PLL_RNGB(agp_pll), agp_pll);
+                      __func__, IO7_PLL_RNGB(agp_pll), agp_pll);
                break;
        }
 
@@ -1044,13 +1044,13 @@ marvel_agp_translate(alpha_agp_info *agp, dma_addr_t addr)
 
        if (addr < agp->aperture.bus_base ||
            addr >= agp->aperture.bus_base + agp->aperture.size) {
-               printk("%s: addr out of range\n", __FUNCTION__);
+               printk("%s: addr out of range\n", __func__);
                return -EINVAL;
        }
 
        pte = aper->arena->ptes[baddr >> PAGE_SHIFT];
        if (!(pte & 1)) {
-               printk("%s: pte not valid\n", __FUNCTION__);
+               printk("%s: pte not valid\n", __func__);
                return -EINVAL;
        } 
        return (pte >> 1) << PAGE_SHIFT;
index f5ca525..c075029 100644 (file)
@@ -336,10 +336,7 @@ t2_direct_map_window1(unsigned long base, unsigned long length)
 
 #if DEBUG_PRINT_FINAL_SETTINGS
        printk("%s: setting WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
-              __FUNCTION__,
-              *(vulp)T2_WBASE1,
-              *(vulp)T2_WMASK1,
-              *(vulp)T2_TBASE1);
+              __func__, *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1);
 #endif
 }
 
@@ -366,10 +363,7 @@ t2_sg_map_window2(struct pci_controller *hose,
 
 #if DEBUG_PRINT_FINAL_SETTINGS
        printk("%s: setting WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n",
-              __FUNCTION__,
-              *(vulp)T2_WBASE2,
-              *(vulp)T2_WMASK2,
-              *(vulp)T2_TBASE2);
+              __func__, *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2);
 #endif
 }
 
@@ -377,15 +371,15 @@ static void __init
 t2_save_configuration(void)
 {
 #if DEBUG_PRINT_INITIAL_SETTINGS
-       printk("%s: HAE_1 was 0x%lx\n", __FUNCTION__, srm_hae); /* HW is 0 */
-       printk("%s: HAE_2 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_2);
-       printk("%s: HAE_3 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_3);
-       printk("%s: HAE_4 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_4);
-       printk("%s: HBASE was 0x%lx\n", __FUNCTION__, *(vulp)T2_HBASE);
+       printk("%s: HAE_1 was 0x%lx\n", __func__, srm_hae); /* HW is 0 */
+       printk("%s: HAE_2 was 0x%lx\n", __func__, *(vulp)T2_HAE_2);
+       printk("%s: HAE_3 was 0x%lx\n", __func__, *(vulp)T2_HAE_3);
+       printk("%s: HAE_4 was 0x%lx\n", __func__, *(vulp)T2_HAE_4);
+       printk("%s: HBASE was 0x%lx\n", __func__, *(vulp)T2_HBASE);
 
-       printk("%s: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n", __FUNCTION__, 
+       printk("%s: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n", __func__,
               *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1);
-       printk("%s: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n", __FUNCTION__, 
+       printk("%s: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n", __func__,
               *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2);
 #endif
 
index 8193266..319fcb7 100644 (file)
@@ -365,21 +365,21 @@ void __init
 titan_init_arch(void)
 {
 #if 0
-       printk("%s: titan_init_arch()\n", __FUNCTION__);
-       printk("%s: CChip registers:\n", __FUNCTION__);
-       printk("%s: CSR_CSC 0x%lx\n", __FUNCTION__, TITAN_cchip->csc.csr);
-       printk("%s: CSR_MTR 0x%lx\n", __FUNCTION__, TITAN_cchip->mtr.csr);
-       printk("%s: CSR_MISC 0x%lx\n", __FUNCTION__, TITAN_cchip->misc.csr);
-       printk("%s: CSR_DIM0 0x%lx\n", __FUNCTION__, TITAN_cchip->dim0.csr);
-       printk("%s: CSR_DIM1 0x%lx\n", __FUNCTION__, TITAN_cchip->dim1.csr);
-       printk("%s: CSR_DIR0 0x%lx\n", __FUNCTION__, TITAN_cchip->dir0.csr);
-       printk("%s: CSR_DIR1 0x%lx\n", __FUNCTION__, TITAN_cchip->dir1.csr);
-       printk("%s: CSR_DRIR 0x%lx\n", __FUNCTION__, TITAN_cchip->drir.csr);
-
-       printk("%s: DChip registers:\n", __FUNCTION__);
-       printk("%s: CSR_DSC 0x%lx\n", __FUNCTION__, TITAN_dchip->dsc.csr);
-       printk("%s: CSR_STR 0x%lx\n", __FUNCTION__, TITAN_dchip->str.csr);
-       printk("%s: CSR_DREV 0x%lx\n", __FUNCTION__, TITAN_dchip->drev.csr);
+       printk("%s: titan_init_arch()\n", __func__);
+       printk("%s: CChip registers:\n", __func__);
+       printk("%s: CSR_CSC 0x%lx\n", __func__, TITAN_cchip->csc.csr);
+       printk("%s: CSR_MTR 0x%lx\n", __func__, TITAN_cchip->mtr.csr);
+       printk("%s: CSR_MISC 0x%lx\n", __func__, TITAN_cchip->misc.csr);
+       printk("%s: CSR_DIM0 0x%lx\n", __func__, TITAN_cchip->dim0.csr);
+       printk("%s: CSR_DIM1 0x%lx\n", __func__, TITAN_cchip->dim1.csr);
+       printk("%s: CSR_DIR0 0x%lx\n", __func__, TITAN_cchip->dir0.csr);
+       printk("%s: CSR_DIR1 0x%lx\n", __func__, TITAN_cchip->dir1.csr);
+       printk("%s: CSR_DRIR 0x%lx\n", __func__, TITAN_cchip->drir.csr);
+
+       printk("%s: DChip registers:\n", __func__);
+       printk("%s: CSR_DSC 0x%lx\n", __func__, TITAN_dchip->dsc.csr);
+       printk("%s: CSR_STR 0x%lx\n", __func__, TITAN_dchip->str.csr);
+       printk("%s: CSR_DREV 0x%lx\n", __func__, TITAN_dchip->drev.csr);
 #endif
 
        boot_cpuid = __hard_smp_processor_id();
@@ -700,13 +700,13 @@ titan_agp_translate(alpha_agp_info *agp, dma_addr_t addr)
 
        if (addr < agp->aperture.bus_base ||
            addr >= agp->aperture.bus_base + agp->aperture.size) {
-               printk("%s: addr out of range\n", __FUNCTION__);
+               printk("%s: addr out of range\n", __func__);
                return -EINVAL;
        }
 
        pte = aper->arena->ptes[baddr >> PAGE_SHIFT];
        if (!(pte & 1)) {
-               printk("%s: pte not valid\n", __FUNCTION__);
+               printk("%s: pte not valid\n", __func__);
                return -EINVAL;
        }
 
index ef91e09..5e7c28f 100644 (file)
@@ -241,8 +241,6 @@ tsunami_probe_write(volatile unsigned long *vaddr)
 #define tsunami_probe_read(ADDR) 1
 #endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */
 
-#define FN __FUNCTION__
-
 static void __init
 tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
 {
@@ -383,27 +381,27 @@ tsunami_init_arch(void)
        /* NXMs just don't matter to Tsunami--unless they make it
           choke completely. */
        tmp = (unsigned long)(TSUNAMI_cchip - 1);
-       printk("%s: probing bogus address:  0x%016lx\n", FN, bogus_addr);
+       printk("%s: probing bogus address:  0x%016lx\n", __func__, bogus_addr);
        printk("\tprobe %s\n",
               tsunami_probe_write((unsigned long *)bogus_addr)
               ? "succeeded" : "failed");
 #endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */
 
 #if 0
-       printk("%s: CChip registers:\n", FN);
-       printk("%s: CSR_CSC 0x%lx\n", FN, TSUNAMI_cchip->csc.csr);
-       printk("%s: CSR_MTR 0x%lx\n", FN, TSUNAMI_cchip.mtr.csr);
-       printk("%s: CSR_MISC 0x%lx\n", FN, TSUNAMI_cchip->misc.csr);
-       printk("%s: CSR_DIM0 0x%lx\n", FN, TSUNAMI_cchip->dim0.csr);
-       printk("%s: CSR_DIM1 0x%lx\n", FN, TSUNAMI_cchip->dim1.csr);
-       printk("%s: CSR_DIR0 0x%lx\n", FN, TSUNAMI_cchip->dir0.csr);
-       printk("%s: CSR_DIR1 0x%lx\n", FN, TSUNAMI_cchip->dir1.csr);
-       printk("%s: CSR_DRIR 0x%lx\n", FN, TSUNAMI_cchip->drir.csr);
+       printk("%s: CChip registers:\n", __func__);
+       printk("%s: CSR_CSC 0x%lx\n", __func__, TSUNAMI_cchip->csc.csr);
+       printk("%s: CSR_MTR 0x%lx\n", __func__, TSUNAMI_cchip.mtr.csr);
+       printk("%s: CSR_MISC 0x%lx\n", __func__, TSUNAMI_cchip->misc.csr);
+       printk("%s: CSR_DIM0 0x%lx\n", __func__, TSUNAMI_cchip->dim0.csr);
+       printk("%s: CSR_DIM1 0x%lx\n", __func__, TSUNAMI_cchip->dim1.csr);
+       printk("%s: CSR_DIR0 0x%lx\n", __func__, TSUNAMI_cchip->dir0.csr);
+       printk("%s: CSR_DIR1 0x%lx\n", __func__, TSUNAMI_cchip->dir1.csr);
+       printk("%s: CSR_DRIR 0x%lx\n", __func__, TSUNAMI_cchip->drir.csr);
 
        printk("%s: DChip registers:\n");
-       printk("%s: CSR_DSC 0x%lx\n", FN, TSUNAMI_dchip->dsc.csr);
-       printk("%s: CSR_STR 0x%lx\n", FN, TSUNAMI_dchip->str.csr);
-       printk("%s: CSR_DREV 0x%lx\n", FN, TSUNAMI_dchip->drev.csr);
+       printk("%s: CSR_DSC 0x%lx\n", __func__, TSUNAMI_dchip->dsc.csr);
+       printk("%s: CSR_STR 0x%lx\n", __func__, TSUNAMI_dchip->str.csr);
+       printk("%s: CSR_DREV 0x%lx\n", __func__, TSUNAMI_dchip->drev.csr);
 #endif
        /* With multiple PCI busses, we play with I/O as physical addrs.  */
        ioport_resource.end = ~0UL;
index 026ba9a..ebc3c89 100644 (file)
@@ -120,6 +120,12 @@ module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs,
 
        nsyms = symtab->sh_size / sizeof(Elf64_Sym);
        chains = kcalloc(nsyms, sizeof(struct got_entry), GFP_KERNEL);
+       if (!chains) {
+               printk(KERN_ERR
+                      "module %s: no memory for symbol chain buffer\n",
+                      me->name);
+               return -ENOMEM;
+       }
 
        got->sh_size = 0;
        got->sh_addralign = 8;
index 7835779..baf5756 100644 (file)
@@ -208,7 +208,7 @@ pdev_save_srm_config(struct pci_dev *dev)
 
        tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
        if (!tmp) {
-               printk(KERN_ERR "%s: kmalloc() failed!\n", __FUNCTION__);
+               printk(KERN_ERR "%s: kmalloc() failed!\n", __func__);
                return;
        }
        tmp->next = srm_saved_configs;
index dd6e334..2179c60 100644 (file)
@@ -79,25 +79,21 @@ iommu_arena_new_node(int nid, struct pci_controller *hose, dma_addr_t base,
 
 #ifdef CONFIG_DISCONTIGMEM
 
-        if (!NODE_DATA(nid) ||
-            (NULL == (arena = alloc_bootmem_node(NODE_DATA(nid),
-                                                 sizeof(*arena))))) {
-                printk("%s: couldn't allocate arena from node %d\n"
-                       "    falling back to system-wide allocation\n",
-                       __FUNCTION__, nid);
-                arena = alloc_bootmem(sizeof(*arena));
-        }
-
-        if (!NODE_DATA(nid) ||
-            (NULL == (arena->ptes = __alloc_bootmem_node(NODE_DATA(nid),
-                                                         mem_size,
-                                                         align,
-                                                         0)))) {
-                printk("%s: couldn't allocate arena ptes from node %d\n"
-                       "    falling back to system-wide allocation\n",
-                       __FUNCTION__, nid);
-                arena->ptes = __alloc_bootmem(mem_size, align, 0);
-        }
+       arena = alloc_bootmem_node(NODE_DATA(nid), sizeof(*arena));
+       if (!NODE_DATA(nid) || !arena) {
+               printk("%s: couldn't allocate arena from node %d\n"
+                      "    falling back to system-wide allocation\n",
+                      __func__, nid);
+               arena = alloc_bootmem(sizeof(*arena));
+       }
+
+       arena->ptes = __alloc_bootmem_node(NODE_DATA(nid), mem_size, align, 0);
+       if (!NODE_DATA(nid) || !arena->ptes) {
+               printk("%s: couldn't allocate arena ptes from node %d\n"
+                      "    falling back to system-wide allocation\n",
+                      __func__, nid);
+               arena->ptes = __alloc_bootmem(mem_size, align, 0);
+       }
 
 #else /* CONFIG_DISCONTIGMEM */
 
index 63c2073..2525692 100644 (file)
@@ -755,7 +755,7 @@ smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry,
        if (atomic_read(&data.unstarted_count) > 0) {
                long start_time = jiffies;
                printk(KERN_ERR "%s: initial timeout -- trying long wait\n",
-                      __FUNCTION__);
+                      __func__);
                timeout = jiffies + 30 * HZ;
                while (atomic_read(&data.unstarted_count) > 0
                       && time_before(jiffies, timeout))
@@ -764,7 +764,7 @@ smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry,
                        long delta = jiffies - start_time;
                        printk(KERN_ERR 
                               "%s: response %ld.%ld seconds into long wait\n",
-                              __FUNCTION__, delta / HZ,
+                              __func__, delta / HZ,
                               (100 * (delta - ((delta / HZ) * HZ))) / HZ);
                }
        }
index f7dd081..78ad7cd 100644 (file)
@@ -199,7 +199,7 @@ srm_env_init(void)
                printk(KERN_INFO "%s: This Alpha system doesn't "
                                "know about SRM (or you've booted "
                                "SRM->MILO->Linux, which gets "
-                               "misdetected)...\n", __FUNCTION__);
+                               "misdetected)...\n", __func__);
                return -ENODEV;
        }
 
index d187d01..e53a1e1 100644 (file)
@@ -259,7 +259,7 @@ alcor_init_pci(void)
        if (dev && dev->devfn == PCI_DEVFN(6,0)) {
                alpha_mv.sys.cia.gru_int_req_bits = XLT_GRU_INT_REQ_BITS; 
                printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n",
-                      __FUNCTION__);
+                      __func__);
        }
        pci_dev_put(dev);
 }
index 922143e..828449c 100644 (file)
@@ -80,7 +80,7 @@ io7_get_irq_ctl(unsigned int irq, struct io7 **pio7)
        if (!(io7 = marvel_find_io7(pid))) {
                printk(KERN_ERR 
                       "%s for nonexistent io7 -- vec %x, pid %d\n",
-                      __FUNCTION__, irq, pid);
+                      __func__, irq, pid);
                return NULL;
        }
 
@@ -90,7 +90,7 @@ io7_get_irq_ctl(unsigned int irq, struct io7 **pio7)
        if (irq >= 0x180) {
                printk(KERN_ERR 
                       "%s for invalid irq -- pid %d adjusted irq %x\n",
-                      __FUNCTION__, pid, irq);
+                      __func__, pid, irq);
                return NULL;
        }
 
@@ -110,8 +110,8 @@ io7_enable_irq(unsigned int irq)
 
        ctl = io7_get_irq_ctl(irq, &io7);
        if (!ctl || !io7) {
-               printk(KERN_ERR "%s: get_ctl failed for irq %x\n", 
-                      __FUNCTION__, irq);
+               printk(KERN_ERR "%s: get_ctl failed for irq %x\n",
+                      __func__, irq);
                return;
        }
                
@@ -130,8 +130,8 @@ io7_disable_irq(unsigned int irq)
 
        ctl = io7_get_irq_ctl(irq, &io7);
        if (!ctl || !io7) {
-               printk(KERN_ERR "%s: get_ctl failed for irq %x\n", 
-                      __FUNCTION__, irq);
+               printk(KERN_ERR "%s: get_ctl failed for irq %x\n",
+                      __func__, irq);
                return;
        }
                
index 906019c..99a7f19 100644 (file)
@@ -454,7 +454,7 @@ sable_lynx_enable_irq(unsigned int irq)
        spin_unlock(&sable_lynx_irq_lock);
 #if 0
        printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
-              __FUNCTION__, mask, bit, irq);
+              __func__, mask, bit, irq);
 #endif
 }
 
@@ -470,7 +470,7 @@ sable_lynx_disable_irq(unsigned int irq)
        spin_unlock(&sable_lynx_irq_lock);
 #if 0
        printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
-              __FUNCTION__, mask, bit, irq);
+              __func__, mask, bit, irq);
 #endif
 }
 
@@ -524,7 +524,7 @@ sable_lynx_srm_device_interrupt(unsigned long vector)
        irq = sable_lynx_irq_swizzle->mask_to_irq[bit];
 #if 0
        printk("%s: vector 0x%lx bit 0x%x irq 0x%x\n",
-              __FUNCTION__, vector, bit, irq);
+              __func__, vector, bit, irq);
 #endif
        handle_irq(irq);
 }
index ee7b900..d4327e4 100644 (file)
@@ -89,7 +89,7 @@ sio_pci_route(void)
        /* First, ALWAYS read and print the original setting. */
        pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
                                  &orig_route_tab);
-       printk("%s: PIRQ original 0x%x new 0x%x\n", __FUNCTION__,
+       printk("%s: PIRQ original 0x%x new 0x%x\n", __func__,
               orig_route_tab, alpha_mv.sys.sio.route_tab);
 
 #if defined(ALPHA_RESTORE_SRM_SETUP)
index 2dc7f9f..dc57790 100644 (file)
@@ -8,6 +8,7 @@
  * This file initializes the trap entry points
  */
 
+#include <linux/jiffies.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
@@ -770,7 +771,7 @@ do_entUnaUser(void __user * va, unsigned long opcode,
              unsigned long reg, struct pt_regs *regs)
 {
        static int cnt = 0;
-       static long last_time = 0;
+       static unsigned long last_time;
 
        unsigned long tmp1, tmp2, tmp3, tmp4;
        unsigned long fake_reg, *reg_addr = &fake_reg;
@@ -781,7 +782,7 @@ do_entUnaUser(void __user * va, unsigned long opcode,
           with the unaliged access.  */
 
        if (!test_thread_flag (TIF_UAC_NOPRINT)) {
-               if (cnt >= 5 && jiffies - last_time > 5*HZ) {
+               if (cnt >= 5 && time_after(jiffies, last_time + 5 * HZ)) {
                        cnt = 0;
                }
                if (++cnt < 5) {
index 37cd547..728bb8f 100644 (file)
@@ -539,6 +539,17 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
        at91_set_B_periph(AT91_PIN_PB28, 0);    /* LCDD23 */
 #endif
 
+       if (ARRAY_SIZE(lcdc_resources) > 2) {
+               void __iomem *fb;
+               struct resource *fb_res = &lcdc_resources[2];
+               size_t fb_len = fb_res->end - fb_res->start + 1;
+
+               fb = ioremap_writecombine(fb_res->start, fb_len);
+               if (fb) {
+                       memset(fb, 0, fb_len);
+                       iounmap(fb, fb_len);
+               }
+       }
        lcdc_data = *data;
        platform_device_register(&at91_lcdc_device);
 }
index dbb9a5f..0546898 100644 (file)
@@ -381,6 +381,20 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
        at91_set_B_periph(AT91_PIN_PC24, 0);    /* LCDD22 */
        at91_set_B_periph(AT91_PIN_PC25, 0);    /* LCDD23 */
 
+#ifdef CONFIG_FB_INTSRAM
+       {
+               void __iomem *fb;
+               struct resource *fb_res = &lcdc_resources[2];
+               size_t fb_len = fb_res->end - fb_res->start + 1;
+
+               fb = ioremap_writecombine(fb_res->start, fb_len);
+               if (fb) {
+                       memset(fb, 0, fb_len);
+                       iounmap(fb, fb_len);
+               }
+       }
+#endif
+
        lcdc_data = *data;
        platform_device_register(&at91_lcdc_device);
 }
index 2687b73..ce48c14 100644 (file)
@@ -274,6 +274,8 @@ static int __init early_parse_fbmem(char *p)
                        printk(KERN_WARNING
                               "Failed to allocate framebuffer memory\n");
                        fbmem_size = 0;
+               } else {
+                       memset(__va(fbmem_start), 0, fbmem_size);
                }
        }
 
index 4207a2b..5b06ffa 100644 (file)
@@ -27,7 +27,6 @@ show_mem(void)
 
        printk("\nMem-info:\n");
        show_free_areas();
-       printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
        i = max_mapnr;
        while (i-- > 0) {
                total++;
index cd13e13..3aa6c82 100644 (file)
@@ -19,6 +19,7 @@ config IA64
        select HAVE_OPROFILE
        select HAVE_KPROBES
        select HAVE_KRETPROBES
+       select HAVE_KVM
        default y
        help
          The Itanium Processor Family is Intel's 64-bit successor to
@@ -589,6 +590,8 @@ config MSPEC
 
 source "fs/Kconfig"
 
+source "arch/ia64/kvm/Kconfig"
+
 source "lib/Kconfig"
 
 #
index f1645c4..ec4cca4 100644 (file)
@@ -57,6 +57,7 @@ core-$(CONFIG_IA64_GENERIC)   += arch/ia64/dig/
 core-$(CONFIG_IA64_HP_ZX1)     += arch/ia64/dig/
 core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
 core-$(CONFIG_IA64_SGI_SN2)    += arch/ia64/sn/
+core-$(CONFIG_KVM)             += arch/ia64/kvm/
 
 drivers-$(CONFIG_PCI)          += arch/ia64/pci/
 drivers-$(CONFIG_IA64_HP_SIM)  += arch/ia64/hp/sim/
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
new file mode 100644 (file)
index 0000000..7914e48
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# KVM configuration
+#
+config HAVE_KVM
+       bool
+
+menuconfig VIRTUALIZATION
+       bool "Virtualization"
+       depends on HAVE_KVM || IA64
+       default y
+       ---help---
+         Say Y here to get to see options for using your Linux host to run other
+         operating systems inside virtual machines (guests).
+         This option alone does not add any kernel code.
+
+         If you say N, all options in this submenu will be skipped and disabled.
+
+if VIRTUALIZATION
+
+config KVM
+       tristate "Kernel-based Virtual Machine (KVM) support"
+       depends on HAVE_KVM && EXPERIMENTAL
+       select PREEMPT_NOTIFIERS
+       select ANON_INODES
+       ---help---
+         Support hosting fully virtualized guest machines using hardware
+         virtualization extensions.  You will need a fairly recent
+         processor equipped with virtualization extensions. You will also
+         need to select one or more of the processor modules below.
+
+         This module provides access to the hardware capabilities through
+         a character device node named /dev/kvm.
+
+         To compile this as a module, choose M here: the module
+         will be called kvm.
+
+         If unsure, say N.
+
+config KVM_INTEL
+       tristate "KVM for Intel Itanium 2 processors support"
+       depends on KVM && m
+       ---help---
+         Provides support for KVM on Itanium 2 processors equipped with the VT
+         extensions.
+
+config KVM_TRACE
+       bool
+
+endif # VIRTUALIZATION
diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile
new file mode 100644 (file)
index 0000000..41b034f
--- /dev/null
@@ -0,0 +1,61 @@
+#This Make file is to generate asm-offsets.h and build source.
+#
+
+#Generate asm-offsets.h for vmm module build
+offsets-file := asm-offsets.h
+
+always  := $(offsets-file)
+targets := $(offsets-file)
+targets += arch/ia64/kvm/asm-offsets.s
+clean-files := $(addprefix $(objtree)/,$(targets) $(obj)/memcpy.S $(obj)/memset.S)
+
+# Default sed regexp - multiline due to syntax constraints
+define sed-y
+       "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"
+endef
+
+quiet_cmd_offsets = GEN     $@
+define cmd_offsets
+       (set -e; \
+        echo "#ifndef __ASM_KVM_OFFSETS_H__"; \
+        echo "#define __ASM_KVM_OFFSETS_H__"; \
+        echo "/*"; \
+        echo " * DO NOT MODIFY."; \
+        echo " *"; \
+        echo " * This file was generated by Makefile"; \
+        echo " *"; \
+        echo " */"; \
+        echo ""; \
+        sed -ne $(sed-y) $<; \
+        echo ""; \
+        echo "#endif" ) > $@
+endef
+# We use internal rules to avoid the "is up to date" message from make
+arch/ia64/kvm/asm-offsets.s: arch/ia64/kvm/asm-offsets.c
+       $(call if_changed_dep,cc_s_c)
+
+$(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s
+       $(call cmd,offsets)
+
+#
+# Makefile for Kernel-based Virtual Machine module
+#
+
+EXTRA_CFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
+
+$(addprefix $(objtree)/,$(obj)/memcpy.S $(obj)/memset.S):
+       $(shell ln -snf ../lib/memcpy.S $(src)/memcpy.S)
+       $(shell ln -snf ../lib/memset.S $(src)/memset.S)
+
+common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o)
+
+kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o
+obj-$(CONFIG_KVM) += kvm.o
+
+FORCE : $(obj)/$(offsets-file)
+EXTRA_CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127
+kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \
+       vtlb.o process.o
+#Add link memcpy and memset to avoid possible structure assignment error
+kvm-intel-objs += memset.o memcpy.o
+obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
diff --git a/arch/ia64/kvm/asm-offsets.c b/arch/ia64/kvm/asm-offsets.c
new file mode 100644 (file)
index 0000000..4e3dc13
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * asm-offsets.c Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed
+ * to extract and format the required data.
+ *
+ * Anthony Xu    <anthony.xu@intel.com>
+ * Xiantao Zhang <xiantao.zhang@intel.com>
+ * Copyright (c) 2007 Intel Corporation  KVM support.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/autoconf.h>
+#include <linux/kvm_host.h>
+
+#include "vcpu.h"
+
+#define task_struct kvm_vcpu
+
+#define DEFINE(sym, val) \
+       asm volatile("\n->" #sym " (%0) " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : :)
+
+#define OFFSET(_sym, _str, _mem) \
+    DEFINE(_sym, offsetof(_str, _mem));
+
+void foo(void)
+{
+       DEFINE(VMM_TASK_SIZE, sizeof(struct kvm_vcpu));
+       DEFINE(VMM_PT_REGS_SIZE, sizeof(struct kvm_pt_regs));
+
+       BLANK();
+
+       DEFINE(VMM_VCPU_META_RR0_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.metaphysical_rr0));
+       DEFINE(VMM_VCPU_META_SAVED_RR0_OFFSET,
+                       offsetof(struct kvm_vcpu,
+                               arch.metaphysical_saved_rr0));
+       DEFINE(VMM_VCPU_VRR0_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.vrr[0]));
+       DEFINE(VMM_VPD_IRR0_OFFSET,
+                       offsetof(struct vpd, irr[0]));
+       DEFINE(VMM_VCPU_ITC_CHECK_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.itc_check));
+       DEFINE(VMM_VCPU_IRQ_CHECK_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.irq_check));
+       DEFINE(VMM_VPD_VHPI_OFFSET,
+                       offsetof(struct vpd, vhpi));
+       DEFINE(VMM_VCPU_VSA_BASE_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.vsa_base));
+       DEFINE(VMM_VCPU_VPD_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.vpd));
+       DEFINE(VMM_VCPU_IRQ_CHECK,
+                       offsetof(struct kvm_vcpu, arch.irq_check));
+       DEFINE(VMM_VCPU_TIMER_PENDING,
+                       offsetof(struct kvm_vcpu, arch.timer_pending));
+       DEFINE(VMM_VCPU_META_SAVED_RR0_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.metaphysical_saved_rr0));
+       DEFINE(VMM_VCPU_MODE_FLAGS_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.mode_flags));
+       DEFINE(VMM_VCPU_ITC_OFS_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.itc_offset));
+       DEFINE(VMM_VCPU_LAST_ITC_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.last_itc));
+       DEFINE(VMM_VCPU_SAVED_GP_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.saved_gp));
+
+       BLANK();
+
+       DEFINE(VMM_PT_REGS_B6_OFFSET,
+                               offsetof(struct kvm_pt_regs, b6));
+       DEFINE(VMM_PT_REGS_B7_OFFSET,
+                               offsetof(struct kvm_pt_regs, b7));
+       DEFINE(VMM_PT_REGS_AR_CSD_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_csd));
+       DEFINE(VMM_PT_REGS_AR_SSD_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_ssd));
+       DEFINE(VMM_PT_REGS_R8_OFFSET,
+                               offsetof(struct kvm_pt_regs, r8));
+       DEFINE(VMM_PT_REGS_R9_OFFSET,
+                               offsetof(struct kvm_pt_regs, r9));
+       DEFINE(VMM_PT_REGS_R10_OFFSET,
+                               offsetof(struct kvm_pt_regs, r10));
+       DEFINE(VMM_PT_REGS_R11_OFFSET,
+                               offsetof(struct kvm_pt_regs, r11));
+       DEFINE(VMM_PT_REGS_CR_IPSR_OFFSET,
+                               offsetof(struct kvm_pt_regs, cr_ipsr));
+       DEFINE(VMM_PT_REGS_CR_IIP_OFFSET,
+                               offsetof(struct kvm_pt_regs, cr_iip));
+       DEFINE(VMM_PT_REGS_CR_IFS_OFFSET,
+                               offsetof(struct kvm_pt_regs, cr_ifs));
+       DEFINE(VMM_PT_REGS_AR_UNAT_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_unat));
+       DEFINE(VMM_PT_REGS_AR_PFS_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_pfs));
+       DEFINE(VMM_PT_REGS_AR_RSC_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_rsc));
+       DEFINE(VMM_PT_REGS_AR_RNAT_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_rnat));
+
+       DEFINE(VMM_PT_REGS_AR_BSPSTORE_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_bspstore));
+       DEFINE(VMM_PT_REGS_PR_OFFSET,
+                               offsetof(struct kvm_pt_regs, pr));
+       DEFINE(VMM_PT_REGS_B0_OFFSET,
+                               offsetof(struct kvm_pt_regs, b0));
+       DEFINE(VMM_PT_REGS_LOADRS_OFFSET,
+                               offsetof(struct kvm_pt_regs, loadrs));
+       DEFINE(VMM_PT_REGS_R1_OFFSET,
+                               offsetof(struct kvm_pt_regs, r1));
+       DEFINE(VMM_PT_REGS_R12_OFFSET,
+                               offsetof(struct kvm_pt_regs, r12));
+       DEFINE(VMM_PT_REGS_R13_OFFSET,
+                               offsetof(struct kvm_pt_regs, r13));
+       DEFINE(VMM_PT_REGS_AR_FPSR_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_fpsr));
+       DEFINE(VMM_PT_REGS_R15_OFFSET,
+                               offsetof(struct kvm_pt_regs, r15));
+       DEFINE(VMM_PT_REGS_R14_OFFSET,
+                               offsetof(struct kvm_pt_regs, r14));
+       DEFINE(VMM_PT_REGS_R2_OFFSET,
+                               offsetof(struct kvm_pt_regs, r2));
+       DEFINE(VMM_PT_REGS_R3_OFFSET,
+                               offsetof(struct kvm_pt_regs, r3));
+       DEFINE(VMM_PT_REGS_R16_OFFSET,
+                               offsetof(struct kvm_pt_regs, r16));
+       DEFINE(VMM_PT_REGS_R17_OFFSET,
+                               offsetof(struct kvm_pt_regs, r17));
+       DEFINE(VMM_PT_REGS_R18_OFFSET,
+                               offsetof(struct kvm_pt_regs, r18));
+       DEFINE(VMM_PT_REGS_R19_OFFSET,
+                               offsetof(struct kvm_pt_regs, r19));
+       DEFINE(VMM_PT_REGS_R20_OFFSET,
+                               offsetof(struct kvm_pt_regs, r20));
+       DEFINE(VMM_PT_REGS_R21_OFFSET,
+                               offsetof(struct kvm_pt_regs, r21));
+       DEFINE(VMM_PT_REGS_R22_OFFSET,
+                               offsetof(struct kvm_pt_regs, r22));
+       DEFINE(VMM_PT_REGS_R23_OFFSET,
+                               offsetof(struct kvm_pt_regs, r23));
+       DEFINE(VMM_PT_REGS_R24_OFFSET,
+                               offsetof(struct kvm_pt_regs, r24));
+       DEFINE(VMM_PT_REGS_R25_OFFSET,
+                               offsetof(struct kvm_pt_regs, r25));
+       DEFINE(VMM_PT_REGS_R26_OFFSET,
+                               offsetof(struct kvm_pt_regs, r26));
+       DEFINE(VMM_PT_REGS_R27_OFFSET,
+                               offsetof(struct kvm_pt_regs, r27));
+       DEFINE(VMM_PT_REGS_R28_OFFSET,
+                               offsetof(struct kvm_pt_regs, r28));
+       DEFINE(VMM_PT_REGS_R29_OFFSET,
+                               offsetof(struct kvm_pt_regs, r29));
+       DEFINE(VMM_PT_REGS_R30_OFFSET,
+                               offsetof(struct kvm_pt_regs, r30));
+       DEFINE(VMM_PT_REGS_R31_OFFSET,
+                               offsetof(struct kvm_pt_regs, r31));
+       DEFINE(VMM_PT_REGS_AR_CCV_OFFSET,
+                               offsetof(struct kvm_pt_regs, ar_ccv));
+       DEFINE(VMM_PT_REGS_F6_OFFSET,
+                               offsetof(struct kvm_pt_regs, f6));
+       DEFINE(VMM_PT_REGS_F7_OFFSET,
+                               offsetof(struct kvm_pt_regs, f7));
+       DEFINE(VMM_PT_REGS_F8_OFFSET,
+                               offsetof(struct kvm_pt_regs, f8));
+       DEFINE(VMM_PT_REGS_F9_OFFSET,
+                               offsetof(struct kvm_pt_regs, f9));
+       DEFINE(VMM_PT_REGS_F10_OFFSET,
+                               offsetof(struct kvm_pt_regs, f10));
+       DEFINE(VMM_PT_REGS_F11_OFFSET,
+                               offsetof(struct kvm_pt_regs, f11));
+       DEFINE(VMM_PT_REGS_R4_OFFSET,
+                               offsetof(struct kvm_pt_regs, r4));
+       DEFINE(VMM_PT_REGS_R5_OFFSET,
+                               offsetof(struct kvm_pt_regs, r5));
+       DEFINE(VMM_PT_REGS_R6_OFFSET,
+                               offsetof(struct kvm_pt_regs, r6));
+       DEFINE(VMM_PT_REGS_R7_OFFSET,
+                               offsetof(struct kvm_pt_regs, r7));
+       DEFINE(VMM_PT_REGS_EML_UNAT_OFFSET,
+                               offsetof(struct kvm_pt_regs, eml_unat));
+       DEFINE(VMM_VCPU_IIPA_OFFSET,
+                               offsetof(struct kvm_vcpu, arch.cr_iipa));
+       DEFINE(VMM_VCPU_OPCODE_OFFSET,
+                               offsetof(struct kvm_vcpu, arch.opcode));
+       DEFINE(VMM_VCPU_CAUSE_OFFSET, offsetof(struct kvm_vcpu, arch.cause));
+       DEFINE(VMM_VCPU_ISR_OFFSET,
+                               offsetof(struct kvm_vcpu, arch.cr_isr));
+       DEFINE(VMM_PT_REGS_R16_SLOT,
+                               (((offsetof(struct kvm_pt_regs, r16)
+                               - sizeof(struct kvm_pt_regs)) >> 3) & 0x3f));
+       DEFINE(VMM_VCPU_MODE_FLAGS_OFFSET,
+                               offsetof(struct kvm_vcpu, arch.mode_flags));
+       DEFINE(VMM_VCPU_GP_OFFSET, offsetof(struct kvm_vcpu, arch.__gp));
+       BLANK();
+
+       DEFINE(VMM_VPD_BASE_OFFSET, offsetof(struct kvm_vcpu, arch.vpd));
+       DEFINE(VMM_VPD_VIFS_OFFSET, offsetof(struct vpd, ifs));
+       DEFINE(VMM_VLSAPIC_INSVC_BASE_OFFSET,
+                       offsetof(struct kvm_vcpu, arch.insvc[0]));
+       DEFINE(VMM_VPD_VPTA_OFFSET, offsetof(struct vpd, pta));
+       DEFINE(VMM_VPD_VPSR_OFFSET, offsetof(struct vpd, vpsr));
+
+       DEFINE(VMM_CTX_R4_OFFSET, offsetof(union context, gr[4]));
+       DEFINE(VMM_CTX_R5_OFFSET, offsetof(union context, gr[5]));
+       DEFINE(VMM_CTX_R12_OFFSET, offsetof(union context, gr[12]));
+       DEFINE(VMM_CTX_R13_OFFSET, offsetof(union context, gr[13]));
+       DEFINE(VMM_CTX_KR0_OFFSET, offsetof(union context, ar[0]));
+       DEFINE(VMM_CTX_KR1_OFFSET, offsetof(union context, ar[1]));
+       DEFINE(VMM_CTX_B0_OFFSET, offsetof(union context, br[0]));
+       DEFINE(VMM_CTX_B1_OFFSET, offsetof(union context, br[1]));
+       DEFINE(VMM_CTX_B2_OFFSET, offsetof(union context, br[2]));
+       DEFINE(VMM_CTX_RR0_OFFSET, offsetof(union context, rr[0]));
+       DEFINE(VMM_CTX_RSC_OFFSET, offsetof(union context, ar[16]));
+       DEFINE(VMM_CTX_BSPSTORE_OFFSET, offsetof(union context, ar[18]));
+       DEFINE(VMM_CTX_RNAT_OFFSET, offsetof(union context, ar[19]));
+       DEFINE(VMM_CTX_FCR_OFFSET, offsetof(union context, ar[21]));
+       DEFINE(VMM_CTX_EFLAG_OFFSET, offsetof(union context, ar[24]));
+       DEFINE(VMM_CTX_CFLG_OFFSET, offsetof(union context, ar[27]));
+       DEFINE(VMM_CTX_FSR_OFFSET, offsetof(union context, ar[28]));
+       DEFINE(VMM_CTX_FIR_OFFSET, offsetof(union context, ar[29]));
+       DEFINE(VMM_CTX_FDR_OFFSET, offsetof(union context, ar[30]));
+       DEFINE(VMM_CTX_UNAT_OFFSET, offsetof(union context, ar[36]));
+       DEFINE(VMM_CTX_FPSR_OFFSET, offsetof(union context, ar[40]));
+       DEFINE(VMM_CTX_PFS_OFFSET, offsetof(union context, ar[64]));
+       DEFINE(VMM_CTX_LC_OFFSET, offsetof(union context, ar[65]));
+       DEFINE(VMM_CTX_DCR_OFFSET, offsetof(union context, cr[0]));
+       DEFINE(VMM_CTX_IVA_OFFSET, offsetof(union context, cr[2]));
+       DEFINE(VMM_CTX_PTA_OFFSET, offsetof(union context, cr[8]));
+       DEFINE(VMM_CTX_IBR0_OFFSET, offsetof(union context, ibr[0]));
+       DEFINE(VMM_CTX_DBR0_OFFSET, offsetof(union context, dbr[0]));
+       DEFINE(VMM_CTX_F2_OFFSET, offsetof(union context, fr[2]));
+       DEFINE(VMM_CTX_F3_OFFSET, offsetof(union context, fr[3]));
+       DEFINE(VMM_CTX_F32_OFFSET, offsetof(union context, fr[32]));
+       DEFINE(VMM_CTX_F33_OFFSET, offsetof(union context, fr[33]));
+       DEFINE(VMM_CTX_PKR0_OFFSET, offsetof(union context, pkr[0]));
+       DEFINE(VMM_CTX_PSR_OFFSET, offsetof(union context, psr));
+       BLANK();
+}
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
new file mode 100644 (file)
index 0000000..6df0732
--- /dev/null
@@ -0,0 +1,1806 @@
+
+/*
+ * kvm_ia64.c: Basic KVM suppport On Itanium series processors
+ *
+ *
+ *     Copyright (C) 2007, Intel Corporation.
+ *     Xiantao Zhang  (xiantao.zhang@intel.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/percpu.h>
+#include <linux/gfp.h>
+#include <linux/fs.h>
+#include <linux/smp.h>
+#include <linux/kvm_host.h>
+#include <linux/kvm.h>
+#include <linux/bitops.h>
+#include <linux/hrtimer.h>
+#include <linux/uaccess.h>
+
+#include <asm/pgtable.h>
+#include <asm/gcc_intrin.h>
+#include <asm/pal.h>
+#include <asm/cacheflush.h>
+#include <asm/div64.h>
+#include <asm/tlb.h>
+
+#include "misc.h"
+#include "vti.h"
+#include "iodev.h"
+#include "ioapic.h"
+#include "lapic.h"
+
+static unsigned long kvm_vmm_base;
+static unsigned long kvm_vsa_base;
+static unsigned long kvm_vm_buffer;
+static unsigned long kvm_vm_buffer_size;
+unsigned long kvm_vmm_gp;
+
+static long vp_env_info;
+
+static struct kvm_vmm_info *kvm_vmm_info;
+
+static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu);
+
+struct kvm_stats_debugfs_item debugfs_entries[] = {
+       { NULL }
+};
+
+
+struct fdesc{
+    unsigned long ip;
+    unsigned long gp;
+};
+
+static void kvm_flush_icache(unsigned long start, unsigned long len)
+{
+       int l;
+
+       for (l = 0; l < (len + 32); l += 32)
+               ia64_fc(start + l);
+
+       ia64_sync_i();
+       ia64_srlz_i();
+}
+
+static void kvm_flush_tlb_all(void)
+{
+       unsigned long i, j, count0, count1, stride0, stride1, addr;
+       long flags;
+
+       addr    = local_cpu_data->ptce_base;
+       count0  = local_cpu_data->ptce_count[0];
+       count1  = local_cpu_data->ptce_count[1];
+       stride0 = local_cpu_data->ptce_stride[0];
+       stride1 = local_cpu_data->ptce_stride[1];
+
+       local_irq_save(flags);
+       for (i = 0; i < count0; ++i) {
+               for (j = 0; j < count1; ++j) {
+                       ia64_ptce(addr);
+                       addr += stride1;
+               }
+               addr += stride0;
+       }
+       local_irq_restore(flags);
+       ia64_srlz_i();                  /* srlz.i implies srlz.d */
+}
+
+long ia64_pal_vp_create(u64 *vpd, u64 *host_iva, u64 *opt_handler)
+{
+       struct ia64_pal_retval iprv;
+
+       PAL_CALL_STK(iprv, PAL_VP_CREATE, (u64)vpd, (u64)host_iva,
+                       (u64)opt_handler);
+
+       return iprv.status;
+}
+
+static  DEFINE_SPINLOCK(vp_lock);
+
+void kvm_arch_hardware_enable(void *garbage)
+{
+       long  status;
+       long  tmp_base;
+       unsigned long pte;
+       unsigned long saved_psr;
+       int slot;
+
+       pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base),
+                               PAGE_KERNEL));
+       local_irq_save(saved_psr);
+       slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
+       if (slot < 0)
+               return;
+       local_irq_restore(saved_psr);
+
+       spin_lock(&vp_lock);
+       status = ia64_pal_vp_init_env(kvm_vsa_base ?
+                               VP_INIT_ENV : VP_INIT_ENV_INITALIZE,
+                       __pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base);
+       if (status != 0) {
+               printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n");
+               return ;
+       }
+
+       if (!kvm_vsa_base) {
+               kvm_vsa_base = tmp_base;
+               printk(KERN_INFO"kvm: kvm_vsa_base:0x%lx\n", kvm_vsa_base);
+       }
+       spin_unlock(&vp_lock);
+       ia64_ptr_entry(0x3, slot);
+}
+
+void kvm_arch_hardware_disable(void *garbage)
+{
+
+       long status;
+       int slot;
+       unsigned long pte;
+       unsigned long saved_psr;
+       unsigned long host_iva = ia64_getreg(_IA64_REG_CR_IVA);
+
+       pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base),
+                               PAGE_KERNEL));
+
+       local_irq_save(saved_psr);
+       slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
+       if (slot < 0)
+               return;
+       local_irq_restore(saved_psr);
+
+       status = ia64_pal_vp_exit_env(host_iva);
+       if (status)
+               printk(KERN_DEBUG"kvm: Failed to disable VT support! :%ld\n",
+                               status);
+       ia64_ptr_entry(0x3, slot);
+}
+
+void kvm_arch_check_processor_compat(void *rtn)
+{
+       *(int *)rtn = 0;
+}
+
+int kvm_dev_ioctl_check_extension(long ext)
+{
+
+       int r;
+
+       switch (ext) {
+       case KVM_CAP_IRQCHIP:
+       case KVM_CAP_USER_MEMORY:
+
+               r = 1;
+               break;
+       default:
+               r = 0;
+       }
+       return r;
+
+}
+
+static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
+                                       gpa_t addr)
+{
+       struct kvm_io_device *dev;
+
+       dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
+
+       return dev;
+}
+
+static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
+       kvm_run->hw.hardware_exit_reason = 1;
+       return 0;
+}
+
+static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       struct kvm_mmio_req *p;
+       struct kvm_io_device *mmio_dev;
+
+       p = kvm_get_vcpu_ioreq(vcpu);
+
+       if ((p->addr & PAGE_MASK) == IOAPIC_DEFAULT_BASE_ADDRESS)
+               goto mmio;
+       vcpu->mmio_needed = 1;
+       vcpu->mmio_phys_addr = kvm_run->mmio.phys_addr = p->addr;
+       vcpu->mmio_size = kvm_run->mmio.len = p->size;
+       vcpu->mmio_is_write = kvm_run->mmio.is_write = !p->dir;
+
+       if (vcpu->mmio_is_write)
+               memcpy(vcpu->mmio_data, &p->data, p->size);
+       memcpy(kvm_run->mmio.data, &p->data, p->size);
+       kvm_run->exit_reason = KVM_EXIT_MMIO;
+       return 0;
+mmio:
+       mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr);
+       if (mmio_dev) {
+               if (!p->dir)
+                       kvm_iodevice_write(mmio_dev, p->addr, p->size,
+                                               &p->data);
+               else
+                       kvm_iodevice_read(mmio_dev, p->addr, p->size,
+                                               &p->data);
+
+       } else
+               printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr);
+       p->state = STATE_IORESP_READY;
+
+       return 1;
+}
+
+static int handle_pal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       struct exit_ctl_data *p;
+
+       p = kvm_get_exit_data(vcpu);
+
+       if (p->exit_reason == EXIT_REASON_PAL_CALL)
+               return kvm_pal_emul(vcpu, kvm_run);
+       else {
+               kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
+               kvm_run->hw.hardware_exit_reason = 2;
+               return 0;
+       }
+}
+
+static int handle_sal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       struct exit_ctl_data *p;
+
+       p = kvm_get_exit_data(vcpu);
+
+       if (p->exit_reason == EXIT_REASON_SAL_CALL) {
+               kvm_sal_emul(vcpu);
+               return 1;
+       } else {
+               kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
+               kvm_run->hw.hardware_exit_reason = 3;
+               return 0;
+       }
+
+}
+
+/*
+ *  offset: address offset to IPI space.
+ *  value:  deliver value.
+ */
+static void vcpu_deliver_ipi(struct kvm_vcpu *vcpu, uint64_t dm,
+                               uint64_t vector)
+{
+       switch (dm) {
+       case SAPIC_FIXED:
+               kvm_apic_set_irq(vcpu, vector, 0);
+               break;
+       case SAPIC_NMI:
+               kvm_apic_set_irq(vcpu, 2, 0);
+               break;
+       case SAPIC_EXTINT:
+               kvm_apic_set_irq(vcpu, 0, 0);
+               break;
+       case SAPIC_INIT:
+       case SAPIC_PMI:
+       default:
+               printk(KERN_ERR"kvm: Unimplemented Deliver reserved IPI!\n");
+               break;
+       }
+}
+
+static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id,
+                       unsigned long eid)
+{
+       union ia64_lid lid;
+       int i;
+
+       for (i = 0; i < KVM_MAX_VCPUS; i++) {
+               if (kvm->vcpus[i]) {
+                       lid.val = VCPU_LID(kvm->vcpus[i]);
+                       if (lid.id == id && lid.eid == eid)
+                               return kvm->vcpus[i];
+               }
+       }
+
+       return NULL;
+}
+
+static int handle_ipi(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       struct exit_ctl_data *p = kvm_get_exit_data(vcpu);
+       struct kvm_vcpu *target_vcpu;
+       struct kvm_pt_regs *regs;
+       union ia64_ipi_a addr = p->u.ipi_data.addr;
+       union ia64_ipi_d data = p->u.ipi_data.data;
+
+       target_vcpu = lid_to_vcpu(vcpu->kvm, addr.id, addr.eid);
+       if (!target_vcpu)
+               return handle_vm_error(vcpu, kvm_run);
+
+       if (!target_vcpu->arch.launched) {
+               regs = vcpu_regs(target_vcpu);
+
+               regs->cr_iip = vcpu->kvm->arch.rdv_sal_data.boot_ip;
+               regs->r1 = vcpu->kvm->arch.rdv_sal_data.boot_gp;
+
+               target_vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+               if (waitqueue_active(&target_vcpu->wq))
+                       wake_up_interruptible(&target_vcpu->wq);
+       } else {
+               vcpu_deliver_ipi(target_vcpu, data.dm, data.vector);
+               if (target_vcpu != vcpu)
+                       kvm_vcpu_kick(target_vcpu);
+       }
+
+       return 1;
+}
+
+struct call_data {
+       struct kvm_ptc_g ptc_g_data;
+       struct kvm_vcpu *vcpu;
+};
+
+static void vcpu_global_purge(void *info)
+{
+       struct call_data *p = (struct call_data *)info;
+       struct kvm_vcpu *vcpu = p->vcpu;
+
+       if (test_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
+               return;
+
+       set_bit(KVM_REQ_PTC_G, &vcpu->requests);
+       if (vcpu->arch.ptc_g_count < MAX_PTC_G_NUM) {
+               vcpu->arch.ptc_g_data[vcpu->arch.ptc_g_count++] =
+                                                       p->ptc_g_data;
+       } else {
+               clear_bit(KVM_REQ_PTC_G, &vcpu->requests);
+               vcpu->arch.ptc_g_count = 0;
+               set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests);
+       }
+}
+
+static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       struct exit_ctl_data *p = kvm_get_exit_data(vcpu);
+       struct kvm *kvm = vcpu->kvm;
+       struct call_data call_data;
+       int i;
+       call_data.ptc_g_data = p->u.ptc_g_data;
+
+       for (i = 0; i < KVM_MAX_VCPUS; i++) {
+               if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state ==
+                                               KVM_MP_STATE_UNINITIALIZED ||
+                                       vcpu == kvm->vcpus[i])
+                       continue;
+
+               if (waitqueue_active(&kvm->vcpus[i]->wq))
+                       wake_up_interruptible(&kvm->vcpus[i]->wq);
+
+               if (kvm->vcpus[i]->cpu != -1) {
+                       call_data.vcpu = kvm->vcpus[i];
+                       smp_call_function_single(kvm->vcpus[i]->cpu,
+                                       vcpu_global_purge, &call_data, 0, 1);
+               } else
+                       printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n");
+
+       }
+       return 1;
+}
+
+static int handle_switch_rr6(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       return 1;
+}
+
+int kvm_emulate_halt(struct kvm_vcpu *vcpu)
+{
+
+       ktime_t kt;
+       long itc_diff;
+       unsigned long vcpu_now_itc;
+
+       unsigned long expires;
+       struct hrtimer *p_ht = &vcpu->arch.hlt_timer;
+       unsigned long cyc_per_usec = local_cpu_data->cyc_per_usec;
+       struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);
+
+       vcpu_now_itc = ia64_getreg(_IA64_REG_AR_ITC) + vcpu->arch.itc_offset;
+
+       if (time_after(vcpu_now_itc, vpd->itm)) {
+               vcpu->arch.timer_check = 1;
+               return 1;
+       }
+       itc_diff = vpd->itm - vcpu_now_itc;
+       if (itc_diff < 0)
+               itc_diff = -itc_diff;
+
+       expires = div64_64(itc_diff, cyc_per_usec);
+       kt = ktime_set(0, 1000 * expires);
+       vcpu->arch.ht_active = 1;
+       hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS);
+
+       if (irqchip_in_kernel(vcpu->kvm)) {
+               vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
+               kvm_vcpu_block(vcpu);
+               hrtimer_cancel(p_ht);
+               vcpu->arch.ht_active = 0;
+
+               if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE)
+                       return -EINTR;
+               return 1;
+       } else {
+               printk(KERN_ERR"kvm: Unsupported userspace halt!");
+               return 0;
+       }
+}
+
+static int handle_vm_shutdown(struct kvm_vcpu *vcpu,
+               struct kvm_run *kvm_run)
+{
+       kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
+       return 0;
+}
+
+static int handle_external_interrupt(struct kvm_vcpu *vcpu,
+               struct kvm_run *kvm_run)
+{
+       return 1;
+}
+
+static int (*kvm_vti_exit_handlers[])(struct kvm_vcpu *vcpu,
+               struct kvm_run *kvm_run) = {
+       [EXIT_REASON_VM_PANIC]              = handle_vm_error,
+       [EXIT_REASON_MMIO_INSTRUCTION]      = handle_mmio,
+       [EXIT_REASON_PAL_CALL]              = handle_pal_call,
+       [EXIT_REASON_SAL_CALL]              = handle_sal_call,
+       [EXIT_REASON_SWITCH_RR6]            = handle_switch_rr6,
+       [EXIT_REASON_VM_DESTROY]            = handle_vm_shutdown,
+       [EXIT_REASON_EXTERNAL_INTERRUPT]    = handle_external_interrupt,
+       [EXIT_REASON_IPI]                   = handle_ipi,
+       [EXIT_REASON_PTC_G]                 = handle_global_purge,
+
+};
+
+static const int kvm_vti_max_exit_handlers =
+               sizeof(kvm_vti_exit_handlers)/sizeof(*kvm_vti_exit_handlers);
+
+static void kvm_prepare_guest_switch(struct kvm_vcpu *vcpu)
+{
+}
+
+static uint32_t kvm_get_exit_reason(struct kvm_vcpu *vcpu)
+{
+       struct exit_ctl_data *p_exit_data;
+
+       p_exit_data = kvm_get_exit_data(vcpu);
+       return p_exit_data->exit_reason;
+}
+
+/*
+ * The guest has exited.  See if we can fix it or if we need userspace
+ * assistance.
+ */
+static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
+{
+       u32 exit_reason = kvm_get_exit_reason(vcpu);
+       vcpu->arch.last_exit = exit_reason;
+
+       if (exit_reason < kvm_vti_max_exit_handlers
+                       && kvm_vti_exit_handlers[exit_reason])
+               return kvm_vti_exit_handlers[exit_reason](vcpu, kvm_run);
+       else {
+               kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
+               kvm_run->hw.hardware_exit_reason = exit_reason;
+       }
+       return 0;
+}
+
+static inline void vti_set_rr6(unsigned long rr6)
+{
+       ia64_set_rr(RR6, rr6);
+       ia64_srlz_i();
+}
+
+static int kvm_insert_vmm_mapping(struct kvm_vcpu *vcpu)
+{
+       unsigned long pte;
+       struct kvm *kvm = vcpu->kvm;
+       int r;
+
+       /*Insert a pair of tr to map vmm*/
+       pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL));
+       r = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
+       if (r < 0)
+               goto out;
+       vcpu->arch.vmm_tr_slot = r;
+       /*Insert a pairt of tr to map data of vm*/
+       pte = pte_val(mk_pte_phys(__pa(kvm->arch.vm_base), PAGE_KERNEL));
+       r = ia64_itr_entry(0x3, KVM_VM_DATA_BASE,
+                                       pte, KVM_VM_DATA_SHIFT);
+       if (r < 0)
+               goto out;
+       vcpu->arch.vm_tr_slot = r;
+       r = 0;
+out:
+       return r;
+
+}
+
+static void kvm_purge_vmm_mapping(struct kvm_vcpu *vcpu)
+{
+
+       ia64_ptr_entry(0x3, vcpu->arch.vmm_tr_slot);
+       ia64_ptr_entry(0x3, vcpu->arch.vm_tr_slot);
+
+}
+
+static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu)
+{
+       int cpu = smp_processor_id();
+
+       if (vcpu->arch.last_run_cpu != cpu ||
+                       per_cpu(last_vcpu, cpu) != vcpu) {
+               per_cpu(last_vcpu, cpu) = vcpu;
+               vcpu->arch.last_run_cpu = cpu;
+               kvm_flush_tlb_all();
+       }
+
+       vcpu->arch.host_rr6 = ia64_get_rr(RR6);
+       vti_set_rr6(vcpu->arch.vmm_rr);
+       return kvm_insert_vmm_mapping(vcpu);
+}
+static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu)
+{
+       kvm_purge_vmm_mapping(vcpu);
+       vti_set_rr6(vcpu->arch.host_rr6);
+}
+
+static int  vti_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       union context *host_ctx, *guest_ctx;
+       int r;
+
+       /*Get host and guest context with guest address space.*/
+       host_ctx = kvm_get_host_context(vcpu);
+       guest_ctx = kvm_get_guest_context(vcpu);
+
+       r = kvm_vcpu_pre_transition(vcpu);
+       if (r < 0)
+               goto out;
+       kvm_vmm_info->tramp_entry(host_ctx, guest_ctx);
+       kvm_vcpu_post_transition(vcpu);
+       r = 0;
+out:
+       return r;
+}
+
+static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       int r;
+
+again:
+       preempt_disable();
+
+       kvm_prepare_guest_switch(vcpu);
+       local_irq_disable();
+
+       if (signal_pending(current)) {
+               local_irq_enable();
+               preempt_enable();
+               r = -EINTR;
+               kvm_run->exit_reason = KVM_EXIT_INTR;
+               goto out;
+       }
+
+       vcpu->guest_mode = 1;
+       kvm_guest_enter();
+
+       r = vti_vcpu_run(vcpu, kvm_run);
+       if (r < 0) {
+               local_irq_enable();
+               preempt_enable();
+               kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+               goto out;
+       }
+
+       vcpu->arch.launched = 1;
+       vcpu->guest_mode = 0;
+       local_irq_enable();
+
+       /*
+        * We must have an instruction between local_irq_enable() and
+        * kvm_guest_exit(), so the timer interrupt isn't delayed by
+        * the interrupt shadow.  The stat.exits increment will do nicely.
+        * But we need to prevent reordering, hence this barrier():
+        */
+       barrier();
+
+       kvm_guest_exit();
+
+       preempt_enable();
+
+       r = kvm_handle_exit(kvm_run, vcpu);
+
+       if (r > 0) {
+               if (!need_resched())
+                       goto again;
+       }
+
+out:
+       if (r > 0) {
+               kvm_resched(vcpu);
+               goto again;
+       }
+
+       return r;
+}
+
+static void kvm_set_mmio_data(struct kvm_vcpu *vcpu)
+{
+       struct kvm_mmio_req *p = kvm_get_vcpu_ioreq(vcpu);
+
+       if (!vcpu->mmio_is_write)
+               memcpy(&p->data, vcpu->mmio_data, 8);
+       p->state = STATE_IORESP_READY;
+}
+
+int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       int r;
+       sigset_t sigsaved;
+
+       vcpu_load(vcpu);
+
+       if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) {
+               kvm_vcpu_block(vcpu);
+               vcpu_put(vcpu);
+               return -EAGAIN;
+       }
+
+       if (vcpu->sigset_active)
+               sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
+
+       if (vcpu->mmio_needed) {
+               memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
+               kvm_set_mmio_data(vcpu);
+               vcpu->mmio_read_completed = 1;
+               vcpu->mmio_needed = 0;
+       }
+       r = __vcpu_run(vcpu, kvm_run);
+
+       if (vcpu->sigset_active)
+               sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+
+       vcpu_put(vcpu);
+       return r;
+}
+
+/*
+ * Allocate 16M memory for every vm to hold its specific data.
+ * Its memory map is defined in kvm_host.h.
+ */
+static struct kvm *kvm_alloc_kvm(void)
+{
+
+       struct kvm *kvm;
+       uint64_t  vm_base;
+
+       vm_base = __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE));
+
+       if (!vm_base)
+               return ERR_PTR(-ENOMEM);
+       printk(KERN_DEBUG"kvm: VM data's base Address:0x%lx\n", vm_base);
+
+       /* Zero all pages before use! */
+       memset((void *)vm_base, 0, KVM_VM_DATA_SIZE);
+
+       kvm = (struct kvm *)(vm_base + KVM_VM_OFS);
+       kvm->arch.vm_base = vm_base;
+
+       return kvm;
+}
+
+struct kvm_io_range {
+       unsigned long start;
+       unsigned long size;
+       unsigned long type;
+};
+
+static const struct kvm_io_range io_ranges[] = {
+       {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER},
+       {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO},
+       {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO},
+       {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC},
+       {PIB_START, PIB_SIZE, GPFN_PIB},
+};
+
+static void kvm_build_io_pmt(struct kvm *kvm)
+{
+       unsigned long i, j;
+
+       /* Mark I/O ranges */
+       for (i = 0; i < (sizeof(io_ranges) / sizeof(struct kvm_io_range));
+                                                       i++) {
+               for (j = io_ranges[i].start;
+                               j < io_ranges[i].start + io_ranges[i].size;
+                               j += PAGE_SIZE)
+                       kvm_set_pmt_entry(kvm, j >> PAGE_SHIFT,
+                                       io_ranges[i].type, 0);
+       }
+
+}
+
+/*Use unused rids to virtualize guest rid.*/
+#define GUEST_PHYSICAL_RR0     0x1739
+#define GUEST_PHYSICAL_RR4     0x2739
+#define VMM_INIT_RR            0x1660
+
+static void kvm_init_vm(struct kvm *kvm)
+{
+       long vm_base;
+
+       BUG_ON(!kvm);
+
+       kvm->arch.metaphysical_rr0 = GUEST_PHYSICAL_RR0;
+       kvm->arch.metaphysical_rr4 = GUEST_PHYSICAL_RR4;
+       kvm->arch.vmm_init_rr = VMM_INIT_RR;
+
+       vm_base = kvm->arch.vm_base;
+       if (vm_base) {
+               kvm->arch.vhpt_base = vm_base + KVM_VHPT_OFS;
+               kvm->arch.vtlb_base = vm_base + KVM_VTLB_OFS;
+               kvm->arch.vpd_base  = vm_base + KVM_VPD_OFS;
+       }
+
+       /*
+        *Fill P2M entries for MMIO/IO ranges
+        */
+       kvm_build_io_pmt(kvm);
+
+}
+
+struct  kvm *kvm_arch_create_vm(void)
+{
+       struct kvm *kvm = kvm_alloc_kvm();
+
+       if (IS_ERR(kvm))
+               return ERR_PTR(-ENOMEM);
+       kvm_init_vm(kvm);
+
+       return kvm;
+
+}
+
+static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm,
+                                       struct kvm_irqchip *chip)
+{
+       int r;
+
+       r = 0;
+       switch (chip->chip_id) {
+       case KVM_IRQCHIP_IOAPIC:
+               memcpy(&chip->chip.ioapic, ioapic_irqchip(kvm),
+                               sizeof(struct kvm_ioapic_state));
+               break;
+       default:
+               r = -EINVAL;
+               break;
+       }
+       return r;
+}
+
+static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
+{
+       int r;
+
+       r = 0;
+       switch (chip->chip_id) {
+       case KVM_IRQCHIP_IOAPIC:
+               memcpy(ioapic_irqchip(kvm),
+                               &chip->chip.ioapic,
+                               sizeof(struct kvm_ioapic_state));
+               break;
+       default:
+               r = -EINVAL;
+               break;
+       }
+       return r;
+}
+
+#define RESTORE_REGS(_x) vcpu->arch._x = regs->_x
+
+int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+       int i;
+       struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);
+       int r;
+
+       vcpu_load(vcpu);
+
+       for (i = 0; i < 16; i++) {
+               vpd->vgr[i] = regs->vpd.vgr[i];
+               vpd->vbgr[i] = regs->vpd.vbgr[i];
+       }
+       for (i = 0; i < 128; i++)
+               vpd->vcr[i] = regs->vpd.vcr[i];
+       vpd->vhpi = regs->vpd.vhpi;
+       vpd->vnat = regs->vpd.vnat;
+       vpd->vbnat = regs->vpd.vbnat;
+       vpd->vpsr = regs->vpd.vpsr;
+
+       vpd->vpr = regs->vpd.vpr;
+
+       r = -EFAULT;
+       r = copy_from_user(&vcpu->arch.guest, regs->saved_guest,
+                                               sizeof(union context));
+       if (r)
+               goto out;
+       r = copy_from_user(vcpu + 1, regs->saved_stack +
+                       sizeof(struct kvm_vcpu),
+                       IA64_STK_OFFSET - sizeof(struct kvm_vcpu));
+       if (r)
+               goto out;
+       vcpu->arch.exit_data =
+               ((struct kvm_vcpu *)(regs->saved_stack))->arch.exit_data;
+
+       RESTORE_REGS(mp_state);
+       RESTORE_REGS(vmm_rr);
+       memcpy(vcpu->arch.itrs, regs->itrs, sizeof(struct thash_data) * NITRS);
+       memcpy(vcpu->arch.dtrs, regs->dtrs, sizeof(struct thash_data) * NDTRS);
+       RESTORE_REGS(itr_regions);
+       RESTORE_REGS(dtr_regions);
+       RESTORE_REGS(tc_regions);
+       RESTORE_REGS(irq_check);
+       RESTORE_REGS(itc_check);
+       RESTORE_REGS(timer_check);
+       RESTORE_REGS(timer_pending);
+       RESTORE_REGS(last_itc);
+       for (i = 0; i < 8; i++) {
+               vcpu->arch.vrr[i] = regs->vrr[i];
+               vcpu->arch.ibr[i] = regs->ibr[i];
+               vcpu->arch.dbr[i] = regs->dbr[i];
+       }
+       for (i = 0; i < 4; i++)
+               vcpu->arch.insvc[i] = regs->insvc[i];
+       RESTORE_REGS(xtp);
+       RESTORE_REGS(metaphysical_rr0);
+       RESTORE_REGS(metaphysical_rr4);
+       RESTORE_REGS(metaphysical_saved_rr0);
+       RESTORE_REGS(metaphysical_saved_rr4);
+       RESTORE_REGS(fp_psr);
+       RESTORE_REGS(saved_gp);
+
+       vcpu->arch.irq_new_pending = 1;
+       vcpu->arch.itc_offset = regs->saved_itc - ia64_getreg(_IA64_REG_AR_ITC);
+       set_bit(KVM_REQ_RESUME, &vcpu->requests);
+
+       vcpu_put(vcpu);
+       r = 0;
+out:
+       return r;
+}
+
+long kvm_arch_vm_ioctl(struct file *filp,
+               unsigned int ioctl, unsigned long arg)
+{
+       struct kvm *kvm = filp->private_data;
+       void __user *argp = (void __user *)arg;
+       int r = -EINVAL;
+
+       switch (ioctl) {
+       case KVM_SET_MEMORY_REGION: {
+               struct kvm_memory_region kvm_mem;
+               struct kvm_userspace_memory_region kvm_userspace_mem;
+
+               r = -EFAULT;
+               if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem))
+                       goto out;
+               kvm_userspace_mem.slot = kvm_mem.slot;
+               kvm_userspace_mem.flags = kvm_mem.flags;
+               kvm_userspace_mem.guest_phys_addr =
+                                       kvm_mem.guest_phys_addr;
+               kvm_userspace_mem.memory_size = kvm_mem.memory_size;
+               r = kvm_vm_ioctl_set_memory_region(kvm,
+                                       &kvm_userspace_mem, 0);
+               if (r)
+                       goto out;
+               break;
+               }
+       case KVM_CREATE_IRQCHIP:
+               r = -EFAULT;
+               r = kvm_ioapic_init(kvm);
+               if (r)
+                       goto out;
+               break;
+       case KVM_IRQ_LINE: {
+               struct kvm_irq_level irq_event;
+
+               r = -EFAULT;
+               if (copy_from_user(&irq_event, argp, sizeof irq_event))
+                       goto out;
+               if (irqchip_in_kernel(kvm)) {
+                       mutex_lock(&kvm->lock);
+                       kvm_ioapic_set_irq(kvm->arch.vioapic,
+                                               irq_event.irq,
+                                               irq_event.level);
+                       mutex_unlock(&kvm->lock);
+                       r = 0;
+               }
+               break;
+               }
+       case KVM_GET_IRQCHIP: {
+               /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+               struct kvm_irqchip chip;
+
+               r = -EFAULT;
+               if (copy_from_user(&chip, argp, sizeof chip))
+                               goto out;
+               r = -ENXIO;
+               if (!irqchip_in_kernel(kvm))
+                       goto out;
+               r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
+               if (r)
+                       goto out;
+               r = -EFAULT;
+               if (copy_to_user(argp, &chip, sizeof chip))
+                               goto out;
+               r = 0;
+               break;
+               }
+       case KVM_SET_IRQCHIP: {
+               /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+               struct kvm_irqchip chip;
+
+               r = -EFAULT;
+               if (copy_from_user(&chip, argp, sizeof chip))
+                               goto out;
+               r = -ENXIO;
+               if (!irqchip_in_kernel(kvm))
+                       goto out;
+               r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
+               if (r)
+                       goto out;
+               r = 0;
+               break;
+               }
+       default:
+               ;
+       }
+out:
+       return r;
+}
+
+int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+               struct kvm_sregs *sregs)
+{
+       return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
+               struct kvm_sregs *sregs)
+{
+       return -EINVAL;
+
+}
+int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
+               struct kvm_translation *tr)
+{
+
+       return -EINVAL;
+}
+
+static int kvm_alloc_vmm_area(void)
+{
+       if (!kvm_vmm_base && (kvm_vm_buffer_size < KVM_VM_BUFFER_SIZE)) {
+               kvm_vmm_base = __get_free_pages(GFP_KERNEL,
+                               get_order(KVM_VMM_SIZE));
+               if (!kvm_vmm_base)
+                       return -ENOMEM;
+
+               memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE);
+               kvm_vm_buffer = kvm_vmm_base + VMM_SIZE;
+
+               printk(KERN_DEBUG"kvm:VMM's Base Addr:0x%lx, vm_buffer:0x%lx\n",
+                               kvm_vmm_base, kvm_vm_buffer);
+       }
+
+       return 0;
+}
+
+static void kvm_free_vmm_area(void)
+{
+       if (kvm_vmm_base) {
+               /*Zero this area before free to avoid bits leak!!*/
+               memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE);
+               free_pages(kvm_vmm_base, get_order(KVM_VMM_SIZE));
+               kvm_vmm_base  = 0;
+               kvm_vm_buffer = 0;
+               kvm_vsa_base = 0;
+       }
+}
+
+/*
+ * Make sure that a cpu that is being hot-unplugged does not have any vcpus
+ * cached on it. Leave it as blank for IA64.
+ */
+void decache_vcpus_on_cpu(int cpu)
+{
+}
+
+static void vti_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+{
+}
+
+static int vti_init_vpd(struct kvm_vcpu *vcpu)
+{
+       int i;
+       union cpuid3_t cpuid3;
+       struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);
+
+       if (IS_ERR(vpd))
+               return PTR_ERR(vpd);
+
+       /* CPUID init */
+       for (i = 0; i < 5; i++)
+               vpd->vcpuid[i] = ia64_get_cpuid(i);
+
+       /* Limit the CPUID number to 5 */
+       cpuid3.value = vpd->vcpuid[3];
+       cpuid3.number = 4;      /* 5 - 1 */
+       vpd->vcpuid[3] = cpuid3.value;
+
+       /*Set vac and vdc fields*/
+       vpd->vac.a_from_int_cr = 1;
+       vpd->vac.a_to_int_cr = 1;
+       vpd->vac.a_from_psr = 1;
+       vpd->vac.a_from_cpuid = 1;
+       vpd->vac.a_cover = 1;
+       vpd->vac.a_bsw = 1;
+       vpd->vac.a_int = 1;
+       vpd->vdc.d_vmsw = 1;
+
+       /*Set virtual buffer*/
+       vpd->virt_env_vaddr = KVM_VM_BUFFER_BASE;
+
+       return 0;
+}
+
+static int vti_create_vp(struct kvm_vcpu *vcpu)
+{
+       long ret;
+       struct vpd *vpd = vcpu->arch.vpd;
+       unsigned long  vmm_ivt;
+
+       vmm_ivt = kvm_vmm_info->vmm_ivt;
+
+       printk(KERN_DEBUG "kvm: vcpu:%p,ivt: 0x%lx\n", vcpu, vmm_ivt);
+
+       ret = ia64_pal_vp_create((u64 *)vpd, (u64 *)vmm_ivt, 0);
+
+       if (ret) {
+               printk(KERN_ERR"kvm: ia64_pal_vp_create failed!\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static void init_ptce_info(struct kvm_vcpu *vcpu)
+{
+       ia64_ptce_info_t ptce = {0};
+
+       ia64_get_ptce(&ptce);
+       vcpu->arch.ptce_base = ptce.base;
+       vcpu->arch.ptce_count[0] = ptce.count[0];
+       vcpu->arch.ptce_count[1] = ptce.count[1];
+       vcpu->arch.ptce_stride[0] = ptce.stride[0];
+       vcpu->arch.ptce_stride[1] = ptce.stride[1];
+}
+
+static void kvm_migrate_hlt_timer(struct kvm_vcpu *vcpu)
+{
+       struct hrtimer *p_ht = &vcpu->arch.hlt_timer;
+
+       if (hrtimer_cancel(p_ht))
+               hrtimer_start(p_ht, p_ht->expires, HRTIMER_MODE_ABS);
+}
+
+static enum hrtimer_restart hlt_timer_fn(struct hrtimer *data)
+{
+       struct kvm_vcpu *vcpu;
+       wait_queue_head_t *q;
+
+       vcpu  = container_of(data, struct kvm_vcpu, arch.hlt_timer);
+       if (vcpu->arch.mp_state != KVM_MP_STATE_HALTED)
+               goto out;
+
+       q = &vcpu->wq;
+       if (waitqueue_active(q)) {
+               vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+               wake_up_interruptible(q);
+       }
+out:
+       vcpu->arch.timer_check = 1;
+       return HRTIMER_NORESTART;
+}
+
+#define PALE_RESET_ENTRY    0x80000000ffffffb0UL
+
+int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
+{
+       struct kvm_vcpu *v;
+       int r;
+       int i;
+       long itc_offset;
+       struct kvm *kvm = vcpu->kvm;
+       struct kvm_pt_regs *regs = vcpu_regs(vcpu);
+
+       union context *p_ctx = &vcpu->arch.guest;
+       struct kvm_vcpu *vmm_vcpu = to_guest(vcpu->kvm, vcpu);
+
+       /*Init vcpu context for first run.*/
+       if (IS_ERR(vmm_vcpu))
+               return PTR_ERR(vmm_vcpu);
+
+       if (vcpu->vcpu_id == 0) {
+               vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+
+               /*Set entry address for first run.*/
+               regs->cr_iip = PALE_RESET_ENTRY;
+
+               /*Initilize itc offset for vcpus*/
+               itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC);
+               for (i = 0; i < MAX_VCPU_NUM; i++) {
+                       v = (struct kvm_vcpu *)((char *)vcpu + VCPU_SIZE * i);
+                       v->arch.itc_offset = itc_offset;
+                       v->arch.last_itc = 0;
+               }
+       } else
+               vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED;
+
+       r = -ENOMEM;
+       vcpu->arch.apic = kzalloc(sizeof(struct kvm_lapic), GFP_KERNEL);
+       if (!vcpu->arch.apic)
+               goto out;
+       vcpu->arch.apic->vcpu = vcpu;
+
+       p_ctx->gr[1] = 0;
+       p_ctx->gr[12] = (unsigned long)((char *)vmm_vcpu + IA64_STK_OFFSET);
+       p_ctx->gr[13] = (unsigned long)vmm_vcpu;
+       p_ctx->psr = 0x1008522000UL;
+       p_ctx->ar[40] = FPSR_DEFAULT; /*fpsr*/
+       p_ctx->caller_unat = 0;
+       p_ctx->pr = 0x0;
+       p_ctx->ar[36] = 0x0; /*unat*/
+       p_ctx->ar[19] = 0x0; /*rnat*/
+       p_ctx->ar[18] = (unsigned long)vmm_vcpu +
+                               ((sizeof(struct kvm_vcpu)+15) & ~15);
+       p_ctx->ar[64] = 0x0; /*pfs*/
+       p_ctx->cr[0] = 0x7e04UL;
+       p_ctx->cr[2] = (unsigned long)kvm_vmm_info->vmm_ivt;
+       p_ctx->cr[8] = 0x3c;
+
+       /*Initilize region register*/
+       p_ctx->rr[0] = 0x30;
+       p_ctx->rr[1] = 0x30;
+       p_ctx->rr[2] = 0x30;
+       p_ctx->rr[3] = 0x30;
+       p_ctx->rr[4] = 0x30;
+       p_ctx->rr[5] = 0x30;
+       p_ctx->rr[7] = 0x30;
+
+       /*Initilize branch register 0*/
+       p_ctx->br[0] = *(unsigned long *)kvm_vmm_info->vmm_entry;
+
+       vcpu->arch.vmm_rr = kvm->arch.vmm_init_rr;
+       vcpu->arch.metaphysical_rr0 = kvm->arch.metaphysical_rr0;
+       vcpu->arch.metaphysical_rr4 = kvm->arch.metaphysical_rr4;
+
+       hrtimer_init(&vcpu->arch.hlt_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+       vcpu->arch.hlt_timer.function = hlt_timer_fn;
+
+       vcpu->arch.last_run_cpu = -1;
+       vcpu->arch.vpd = (struct vpd *)VPD_ADDR(vcpu->vcpu_id);
+       vcpu->arch.vsa_base = kvm_vsa_base;
+       vcpu->arch.__gp = kvm_vmm_gp;
+       vcpu->arch.dirty_log_lock_pa = __pa(&kvm->arch.dirty_log_lock);
+       vcpu->arch.vhpt.hash = (struct thash_data *)VHPT_ADDR(vcpu->vcpu_id);
+       vcpu->arch.vtlb.hash = (struct thash_data *)VTLB_ADDR(vcpu->vcpu_id);
+       init_ptce_info(vcpu);
+
+       r = 0;
+out:
+       return r;
+}
+
+static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id)
+{
+       unsigned long psr;
+       int r;
+
+       local_irq_save(psr);
+       r = kvm_insert_vmm_mapping(vcpu);
+       if (r)
+               goto fail;
+       r = kvm_vcpu_init(vcpu, vcpu->kvm, id);
+       if (r)
+               goto fail;
+
+       r = vti_init_vpd(vcpu);
+       if (r) {
+               printk(KERN_DEBUG"kvm: vpd init error!!\n");
+               goto uninit;
+       }
+
+       r = vti_create_vp(vcpu);
+       if (r)
+               goto uninit;
+
+       kvm_purge_vmm_mapping(vcpu);
+       local_irq_restore(psr);
+
+       return 0;
+uninit:
+       kvm_vcpu_uninit(vcpu);
+fail:
+       return r;
+}
+
+struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
+               unsigned int id)
+{
+       struct kvm_vcpu *vcpu;
+       unsigned long vm_base = kvm->arch.vm_base;
+       int r;
+       int cpu;
+
+       r = -ENOMEM;
+       if (!vm_base) {
+               printk(KERN_ERR"kvm: Create vcpu[%d] error!\n", id);
+               goto fail;
+       }
+       vcpu = (struct kvm_vcpu *)(vm_base + KVM_VCPU_OFS + VCPU_SIZE * id);
+       vcpu->kvm = kvm;
+
+       cpu = get_cpu();
+       vti_vcpu_load(vcpu, cpu);
+       r = vti_vcpu_setup(vcpu, id);
+       put_cpu();
+
+       if (r) {
+               printk(KERN_DEBUG"kvm: vcpu_setup error!!\n");
+               goto fail;
+       }
+
+       return vcpu;
+fail:
+       return ERR_PTR(r);
+}
+
+int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
+{
+       return 0;
+}
+
+int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+       return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+       return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
+               struct kvm_debug_guest *dbg)
+{
+       return -EINVAL;
+}
+
+static void free_kvm(struct kvm *kvm)
+{
+       unsigned long vm_base = kvm->arch.vm_base;
+
+       if (vm_base) {
+               memset((void *)vm_base, 0, KVM_VM_DATA_SIZE);
+               free_pages(vm_base, get_order(KVM_VM_DATA_SIZE));
+       }
+
+}
+
+static void kvm_release_vm_pages(struct kvm *kvm)
+{
+       struct kvm_memory_slot *memslot;
+       int i, j;
+       unsigned long base_gfn;
+
+       for (i = 0; i < kvm->nmemslots; i++) {
+               memslot = &kvm->memslots[i];
+               base_gfn = memslot->base_gfn;
+
+               for (j = 0; j < memslot->npages; j++) {
+                       if (memslot->rmap[j])
+                               put_page((struct page *)memslot->rmap[j]);
+               }
+       }
+}
+
+void kvm_arch_destroy_vm(struct kvm *kvm)
+{
+       kfree(kvm->arch.vioapic);
+       kvm_release_vm_pages(kvm);
+       kvm_free_physmem(kvm);
+       free_kvm(kvm);
+}
+
+void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+{
+       if (cpu != vcpu->cpu) {
+               vcpu->cpu = cpu;
+               if (vcpu->arch.ht_active)
+                       kvm_migrate_hlt_timer(vcpu);
+       }
+}
+
+#define SAVE_REGS(_x)  regs->_x = vcpu->arch._x
+
+int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+       int i;
+       int r;
+       struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);
+       vcpu_load(vcpu);
+
+       for (i = 0; i < 16; i++) {
+               regs->vpd.vgr[i] = vpd->vgr[i];
+               regs->vpd.vbgr[i] = vpd->vbgr[i];
+       }
+       for (i = 0; i < 128; i++)
+               regs->vpd.vcr[i] = vpd->vcr[i];
+       regs->vpd.vhpi = vpd->vhpi;
+       regs->vpd.vnat = vpd->vnat;
+       regs->vpd.vbnat = vpd->vbnat;
+       regs->vpd.vpsr = vpd->vpsr;
+       regs->vpd.vpr = vpd->vpr;
+
+       r = -EFAULT;
+       r = copy_to_user(regs->saved_guest, &vcpu->arch.guest,
+                                       sizeof(union context));
+       if (r)
+               goto out;
+       r = copy_to_user(regs->saved_stack, (void *)vcpu, IA64_STK_OFFSET);
+       if (r)
+               goto out;
+       SAVE_REGS(mp_state);
+       SAVE_REGS(vmm_rr);
+       memcpy(regs->itrs, vcpu->arch.itrs, sizeof(struct thash_data) * NITRS);
+       memcpy(regs->dtrs, vcpu->arch.dtrs, sizeof(struct thash_data) * NDTRS);
+       SAVE_REGS(itr_regions);
+       SAVE_REGS(dtr_regions);
+       SAVE_REGS(tc_regions);
+       SAVE_REGS(irq_check);
+       SAVE_REGS(itc_check);
+       SAVE_REGS(timer_check);
+       SAVE_REGS(timer_pending);
+       SAVE_REGS(last_itc);
+       for (i = 0; i < 8; i++) {
+               regs->vrr[i] = vcpu->arch.vrr[i];
+               regs->ibr[i] = vcpu->arch.ibr[i];
+               regs->dbr[i] = vcpu->arch.dbr[i];
+       }
+       for (i = 0; i < 4; i++)
+               regs->insvc[i] = vcpu->arch.insvc[i];
+       regs->saved_itc = vcpu->arch.itc_offset + ia64_getreg(_IA64_REG_AR_ITC);
+       SAVE_REGS(xtp);
+       SAVE_REGS(metaphysical_rr0);
+       SAVE_REGS(metaphysical_rr4);
+       SAVE_REGS(metaphysical_saved_rr0);
+       SAVE_REGS(metaphysical_saved_rr4);
+       SAVE_REGS(fp_psr);
+       SAVE_REGS(saved_gp);
+       vcpu_put(vcpu);
+       r = 0;
+out:
+       return r;
+}
+
+void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
+{
+
+       hrtimer_cancel(&vcpu->arch.hlt_timer);
+       kfree(vcpu->arch.apic);
+}
+
+
+long kvm_arch_vcpu_ioctl(struct file *filp,
+               unsigned int ioctl, unsigned long arg)
+{
+       return -EINVAL;
+}
+
+int kvm_arch_set_memory_region(struct kvm *kvm,
+               struct kvm_userspace_memory_region *mem,
+               struct kvm_memory_slot old,
+               int user_alloc)
+{
+       unsigned long i;
+       struct page *page;
+       int npages = mem->memory_size >> PAGE_SHIFT;
+       struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot];
+       unsigned long base_gfn = memslot->base_gfn;
+
+       for (i = 0; i < npages; i++) {
+               page = gfn_to_page(kvm, base_gfn + i);
+               kvm_set_pmt_entry(kvm, base_gfn + i,
+                               page_to_pfn(page) << PAGE_SHIFT,
+                               _PAGE_AR_RWX|_PAGE_MA_WB);
+               memslot->rmap[i] = (unsigned long)page;
+       }
+
+       return 0;
+}
+
+
+long kvm_arch_dev_ioctl(struct file *filp,
+               unsigned int ioctl, unsigned long arg)
+{
+       return -EINVAL;
+}
+
+void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
+{
+       kvm_vcpu_uninit(vcpu);
+}
+
+static int vti_cpu_has_kvm_support(void)
+{
+       long  avail = 1, status = 1, control = 1;
+       long ret;
+
+       ret = ia64_pal_proc_get_features(&avail, &status, &control, 0);
+       if (ret)
+               goto out;
+
+       if (!(avail & PAL_PROC_VM_BIT))
+               goto out;
+
+       printk(KERN_DEBUG"kvm: Hardware Supports VT\n");
+
+       ret = ia64_pal_vp_env_info(&kvm_vm_buffer_size, &vp_env_info);
+       if (ret)
+               goto out;
+       printk(KERN_DEBUG"kvm: VM Buffer Size:0x%lx\n", kvm_vm_buffer_size);
+
+       if (!(vp_env_info & VP_OPCODE)) {
+               printk(KERN_WARNING"kvm: No opcode ability on hardware, "
+                               "vm_env_info:0x%lx\n", vp_env_info);
+       }
+
+       return 1;
+out:
+       return 0;
+}
+
+static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
+                                               struct module *module)
+{
+       unsigned long module_base;
+       unsigned long vmm_size;
+
+       unsigned long vmm_offset, func_offset, fdesc_offset;
+       struct fdesc *p_fdesc;
+
+       BUG_ON(!module);
+
+       if (!kvm_vmm_base) {
+               printk("kvm: kvm area hasn't been initilized yet!!\n");
+               return -EFAULT;
+       }
+
+       /*Calculate new position of relocated vmm module.*/
+       module_base = (unsigned long)module->module_core;
+       vmm_size = module->core_size;
+       if (unlikely(vmm_size > KVM_VMM_SIZE))
+               return -EFAULT;
+
+       memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size);
+       kvm_flush_icache(kvm_vmm_base, vmm_size);
+
+       /*Recalculate kvm_vmm_info based on new VMM*/
+       vmm_offset = vmm_info->vmm_ivt - module_base;
+       kvm_vmm_info->vmm_ivt = KVM_VMM_BASE + vmm_offset;
+       printk(KERN_DEBUG"kvm: Relocated VMM's IVT Base Addr:%lx\n",
+                       kvm_vmm_info->vmm_ivt);
+
+       fdesc_offset = (unsigned long)vmm_info->vmm_entry - module_base;
+       kvm_vmm_info->vmm_entry = (kvm_vmm_entry *)(KVM_VMM_BASE +
+                                                       fdesc_offset);
+       func_offset = *(unsigned long *)vmm_info->vmm_entry - module_base;
+       p_fdesc = (struct fdesc *)(kvm_vmm_base + fdesc_offset);
+       p_fdesc->ip = KVM_VMM_BASE + func_offset;
+       p_fdesc->gp = KVM_VMM_BASE+(p_fdesc->gp - module_base);
+
+       printk(KERN_DEBUG"kvm: Relocated VMM's Init Entry Addr:%lx\n",
+                       KVM_VMM_BASE+func_offset);
+
+       fdesc_offset = (unsigned long)vmm_info->tramp_entry - module_base;
+       kvm_vmm_info->tramp_entry = (kvm_tramp_entry *)(KVM_VMM_BASE +
+                       fdesc_offset);
+       func_offset = *(unsigned long *)vmm_info->tramp_entry - module_base;
+       p_fdesc = (struct fdesc *)(kvm_vmm_base + fdesc_offset);
+       p_fdesc->ip = KVM_VMM_BASE + func_offset;
+       p_fdesc->gp = KVM_VMM_BASE + (p_fdesc->gp - module_base);
+
+       kvm_vmm_gp = p_fdesc->gp;
+
+       printk(KERN_DEBUG"kvm: Relocated VMM's Entry IP:%p\n",
+                                               kvm_vmm_info->vmm_entry);
+       printk(KERN_DEBUG"kvm: Relocated VMM's Trampoline Entry IP:0x%lx\n",
+                                               KVM_VMM_BASE + func_offset);
+
+       return 0;
+}
+
+int kvm_arch_init(void *opaque)
+{
+       int r;
+       struct kvm_vmm_info *vmm_info = (struct kvm_vmm_info *)opaque;
+
+       if (!vti_cpu_has_kvm_support()) {
+               printk(KERN_ERR "kvm: No Hardware Virtualization Support!\n");
+               r = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (kvm_vmm_info) {
+               printk(KERN_ERR "kvm: Already loaded VMM module!\n");
+               r = -EEXIST;
+               goto out;
+       }
+
+       r = -ENOMEM;
+       kvm_vmm_info = kzalloc(sizeof(struct kvm_vmm_info), GFP_KERNEL);
+       if (!kvm_vmm_info)
+               goto out;
+
+       if (kvm_alloc_vmm_area())
+               goto out_free0;
+
+       r = kvm_relocate_vmm(vmm_info, vmm_info->module);
+       if (r)
+               goto out_free1;
+
+       return 0;
+
+out_free1:
+       kvm_free_vmm_area();
+out_free0:
+       kfree(kvm_vmm_info);
+out:
+       return r;
+}
+
+void kvm_arch_exit(void)
+{
+       kvm_free_vmm_area();
+       kfree(kvm_vmm_info);
+       kvm_vmm_info = NULL;
+}
+
+static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
+               struct kvm_dirty_log *log)
+{
+       struct kvm_memory_slot *memslot;
+       int r, i;
+       long n, base;
+       unsigned long *dirty_bitmap = (unsigned long *)((void *)kvm - KVM_VM_OFS
+                                       + KVM_MEM_DIRTY_LOG_OFS);
+
+       r = -EINVAL;
+       if (log->slot >= KVM_MEMORY_SLOTS)
+               goto out;
+
+       memslot = &kvm->memslots[log->slot];
+       r = -ENOENT;
+       if (!memslot->dirty_bitmap)
+               goto out;
+
+       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       base = memslot->base_gfn / BITS_PER_LONG;
+
+       for (i = 0; i < n/sizeof(long); ++i) {
+               memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
+               dirty_bitmap[base + i] = 0;
+       }
+       r = 0;
+out:
+       return r;
+}
+
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
+               struct kvm_dirty_log *log)
+{
+       int r;
+       int n;
+       struct kvm_memory_slot *memslot;
+       int is_dirty = 0;
+
+       spin_lock(&kvm->arch.dirty_log_lock);
+
+       r = kvm_ia64_sync_dirty_log(kvm, log);
+       if (r)
+               goto out;
+
+       r = kvm_get_dirty_log(kvm, log, &is_dirty);
+       if (r)
+               goto out;
+
+       /* If nothing is dirty, don't bother messing with page tables. */
+       if (is_dirty) {
+               kvm_flush_remote_tlbs(kvm);
+               memslot = &kvm->memslots[log->slot];
+               n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+               memset(memslot->dirty_bitmap, 0, n);
+       }
+       r = 0;
+out:
+       spin_unlock(&kvm->arch.dirty_log_lock);
+       return r;
+}
+
+int kvm_arch_hardware_setup(void)
+{
+       return 0;
+}
+
+void kvm_arch_hardware_unsetup(void)
+{
+}
+
+static void vcpu_kick_intr(void *info)
+{
+#ifdef DEBUG