Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelv...
Linus Torvalds [Sat, 6 Mar 2010 19:33:09 +0000 (11:33 -0800)]
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging: (23 commits)
  hwmon: Remove the deprecated adt7473 driver
  hwmon: Fix off-by-one kind values
  hwmon: (tmp421) Fix temperature conversions
  hwmon: (tmp421) Restore missing inputs
  hwmon: Driver for Andigilog aSC7621 family monitoring chips
  hwmon: (adt7411) Improve locking
  hwmon: Add driver for ADT7411 voltage and temperature sensor
  hwmon: (w83793) Add watchdog functionality
  hwmon: (g760a) Make rpm_from_cnt static
  hwmon: (it87) Validate auto pwm settings
  hwmon: (it87) Add support for old automatic fan speed control
  hwmon: (it87) Drop dead web links in documentation
  hwmon: (it87) Add an entry in MAINTAINERS
  hwmon: (it87) Use strict_strtol instead of simple_strtol
  hwmon: (it87) Fix many checkpatch errors and warnings
  hwmon: (it87) Add support for beep on alarm
  hwmon: (it87) Create vid attributes by group
  hwmon: (it87) Refactor attributes creation and removal
  hwmon: (it87) Expose the PWM/temperature mappings
  hwmon: (it87) Display fan outputs in automatic mode as such
  ...

527 files changed:
.gitignore
Documentation/ABI/stable/sysfs-devices-node [new file with mode: 0644]
Documentation/fault-injection/provoke-crashes.txt [new file with mode: 0644]
Documentation/feature-removal-schedule.txt
Documentation/filesystems/Locking
Documentation/filesystems/nfs/nfs41-server.txt
Documentation/filesystems/proc.txt
Documentation/gpio.txt
Documentation/init.txt [new file with mode: 0644]
Documentation/kprobes.txt
Documentation/kvm/api.txt
Documentation/vm/slub.txt
MAINTAINERS
arch/Kconfig
arch/alpha/kernel/osf_sys.c
arch/cris/Kconfig
arch/cris/arch-v32/drivers/cryptocop.c
arch/cris/arch-v32/mach-fs/arbiter.c
arch/cris/kernel/time.c
arch/frv/include/asm/pci.h
arch/ia64/include/asm/elf.h
arch/ia64/kernel/Makefile
arch/ia64/kernel/elfcore.c [new file with mode: 0644]
arch/ia64/kernel/perfmon.c
arch/ia64/kvm/Kconfig
arch/ia64/kvm/kvm-ia64.c
arch/ia64/kvm/kvm_fw.c
arch/ia64/kvm/mmio.c
arch/ia64/kvm/vcpu.c
arch/ia64/mm/init.c
arch/powerpc/include/asm/kvm_asm.h
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/include/asm/kvm_book3s_64_asm.h
arch/powerpc/include/asm/kvm_e500.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/reg.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kvm/44x_emulate.c
arch/powerpc/kvm/44x_tlb.c
arch/powerpc/kvm/Kconfig
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/book3s_64_emulate.c
arch/powerpc/kvm/book3s_64_exports.c
arch/powerpc/kvm/book3s_64_interrupts.S
arch/powerpc/kvm/book3s_64_mmu.c
arch/powerpc/kvm/book3s_64_rmhandlers.S
arch/powerpc/kvm/book3s_64_slb.S
arch/powerpc/kvm/booke.c
arch/powerpc/kvm/booke_emulate.c
arch/powerpc/kvm/e500.c
arch/powerpc/kvm/e500_emulate.c
arch/powerpc/kvm/e500_tlb.c
arch/powerpc/kvm/emulate.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/mm/numa.c
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/kvm-s390.h
arch/um/.gitignore [new file with mode: 0644]
arch/um/drivers/line.c
arch/um/sys-i386/Makefile
arch/um/sys-i386/asm/elf.h
arch/um/sys-i386/elfcore.c [new file with mode: 0644]
arch/x86/Kconfig
arch/x86/include/asm/Kbuild
arch/x86/include/asm/alternative.h
arch/x86/include/asm/hyperv.h [new file with mode: 0644]
arch/x86/include/asm/kprobes.h
arch/x86/include/asm/kvm_emulate.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/kvm_para.h
arch/x86/include/asm/svm.h
arch/x86/include/asm/vmx.h
arch/x86/kernel/alternative.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/kprobes.c
arch/x86/kernel/vsyscall_64.c
arch/x86/kvm/Kconfig
arch/x86/kvm/emulate.c
arch/x86/kvm/i8254.c
arch/x86/kvm/i8254.h
arch/x86/kvm/i8259.c
arch/x86/kvm/irq.h
arch/x86/kvm/kvm_cache_regs.h
arch/x86/kvm/lapic.c
arch/x86/kvm/lapic.h
arch/x86/kvm/mmu.c
arch/x86/kvm/mmu.h
arch/x86/kvm/paging_tmpl.h
arch/x86/kvm/svm.c
arch/x86/kvm/trace.h
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
crypto/ahash.c
crypto/authenc.c
crypto/md5.c
drivers/Kconfig
drivers/clocksource/Kconfig [deleted file]
drivers/cpuidle/governors/menu.c
drivers/dma/ioat/dma.c
drivers/eisa/eisa-bus.c
drivers/firmware/memmap.c
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/cs5535-gpio.c
drivers/gpio/gpiolib.c
drivers/gpio/it8761e_gpio.c [new file with mode: 0644]
drivers/gpio/max7300.c [new file with mode: 0644]
drivers/gpio/max7301.c
drivers/gpio/max730x.c [new file with mode: 0644]
drivers/gpio/pca953x.c
drivers/gpio/pl061.c
drivers/gpio/timbgpio.c
drivers/gpu/drm/Kconfig
drivers/hwmon/adcxx.c
drivers/hwmon/vt8231.c
drivers/i2c/busses/i2c-designware.c
drivers/infiniband/core/mad.c
drivers/input/touchscreen/mc13783_ts.c
drivers/mfd/htc-egpio.c
drivers/mfd/mc13783-core.c
drivers/misc/Kconfig
drivers/misc/iwmc3200top/main.c
drivers/misc/lkdtm.c
drivers/misc/sgi-xp/xpnet.c
drivers/mmc/core/core.c
drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_io.c
drivers/mmc/host/Kconfig
drivers/mmc/host/Makefile
drivers/mmc/host/at91_mci.c
drivers/mmc/host/bfin_sdh.c
drivers/mmc/host/davinci_mmc.c
drivers/mmc/host/ricoh_mmc.c [deleted file]
drivers/mmc/host/s3cmci.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci.c
drivers/mtd/ubi/build.c
drivers/mtd/ubi/debug.h
drivers/mtd/ubi/io.c
drivers/mtd/ubi/scan.c
drivers/mtd/ubi/wl.c
drivers/net/gianfar.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbevf/ixgbevf_main.c
drivers/net/wireless/ath/ar9170/main.c
drivers/net/wireless/iwmc3200wifi/debugfs.c
drivers/net/wireless/iwmc3200wifi/rx.c
drivers/pci/quirks.c
drivers/rtc/class.c
drivers/rtc/rtc-at91sam9.c
drivers/rtc/rtc-coh901331.c
drivers/rtc/rtc-ep93xx.c
drivers/rtc/rtc-mc13783.c
drivers/rtc/rtc-mxc.c
drivers/rtc/rtc-pcf2123.c
drivers/rtc/rtc-twl.c
drivers/staging/pohmelfs/inode.c
drivers/video/console/Kconfig
drivers/video/console/vgacon.c
drivers/xen/Kconfig
fs/9p/fid.c
fs/9p/v9fs.c
fs/9p/v9fs.h
fs/9p/vfs_dir.c
fs/9p/vfs_file.c
fs/9p/vfs_inode.c
fs/adfs/adfs.h
fs/adfs/inode.c
fs/affs/affs.h
fs/affs/inode.c
fs/afs/internal.h
fs/afs/super.c
fs/afs/write.c
fs/attr.c
fs/bfs/inode.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/binfmt_flat.c
fs/btrfs/ctree.h
fs/btrfs/inode.c
fs/compat_binfmt_elf.c
fs/compat_ioctl.c
fs/exec.c
fs/exofs/exofs.h
fs/exofs/inode.c
fs/ext2/balloc.c
fs/ext2/ext2.h
fs/ext2/file.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/namei.c
fs/ext2/super.c
fs/ext2/xattr.c
fs/ext3/balloc.c
fs/ext3/file.c
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/namei.c
fs/ext3/super.c
fs/ext3/xattr.c
fs/ext4/balloc.c
fs/ext4/block_validity.c
fs/ext4/dir.c
fs/ext4/ext4.h
fs/ext4/ext4_jbd2.c
fs/ext4/ext4_jbd2.h
fs/ext4/extents.c
fs/ext4/file.c
fs/ext4/fsync.c
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/mballoc.c
fs/ext4/mballoc.h
fs/ext4/migrate.c
fs/ext4/move_extent.c
fs/ext4/namei.c
fs/ext4/resize.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/fat/inode.c
fs/fcntl.c
fs/file.c
fs/file_table.c
fs/fs-writeback.c
fs/gfs2/quota.c
fs/gfs2/quota.h
fs/gfs2/super.c
fs/gfs2/sys.c
fs/hfs/hfs_fs.h
fs/hfs/inode.c
fs/hfsplus/super.c
fs/inode.c
fs/jbd/commit.c
fs/jbd/transaction.c
fs/jbd2/checkpoint.c
fs/jbd2/commit.c
fs/jbd2/journal.c
fs/jbd2/transaction.c
fs/jfs/acl.c
fs/jfs/file.c
fs/jfs/inode.c
fs/jfs/jfs_acl.h
fs/jfs/jfs_dtree.c
fs/jfs/jfs_extent.c
fs/jfs/jfs_inode.c
fs/jfs/jfs_inode.h
fs/jfs/jfs_xtree.c
fs/jfs/namei.c
fs/jfs/super.c
fs/jfs/xattr.c
fs/lockd/host.c
fs/lockd/mon.c
fs/lockd/svc.c
fs/minix/inode.c
fs/namei.c
fs/nfs/callback.c
fs/nfs/callback.h
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/dns_resolve.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs3proc.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
fs/nfs/nfs4renewd.c
fs/nfs/nfs4state.c
fs/nfs/nfs4xdr.c
fs/nfs/proc.c
fs/nfs/symlink.c
fs/nfs/write.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/nfsd/vfs.c
fs/ntfs/dir.c
fs/ntfs/file.c
fs/ntfs/inode.c
fs/ntfs/inode.h
fs/ntfs/super.c
fs/ocfs2/alloc.c
fs/ocfs2/aops.c
fs/ocfs2/dir.c
fs/ocfs2/file.c
fs/ocfs2/inode.c
fs/ocfs2/namei.c
fs/ocfs2/quota_global.c
fs/ocfs2/quota_local.c
fs/ocfs2/refcounttree.c
fs/omfs/inode.c
fs/open.c
fs/proc/array.c
fs/proc/generic.c
fs/proc/task_mmu.c
fs/quota/Kconfig
fs/quota/Makefile
fs/quota/compat.c [new file with mode: 0644]
fs/quota/dquot.c
fs/quota/netlink.c [new file with mode: 0644]
fs/quota/quota.c
fs/reiserfs/bitmap.c
fs/reiserfs/file.c
fs/reiserfs/inode.c
fs/reiserfs/namei.c
fs/reiserfs/stree.c
fs/reiserfs/super.c
fs/reiserfs/xattr.c
fs/select.c
fs/squashfs/Makefile
fs/squashfs/block.c
fs/squashfs/cache.c
fs/squashfs/decompressor.c [new file with mode: 0644]
fs/squashfs/decompressor.h [new file with mode: 0644]
fs/squashfs/dir.c
fs/squashfs/export.c
fs/squashfs/file.c
fs/squashfs/fragment.c
fs/squashfs/id.c
fs/squashfs/inode.c
fs/squashfs/namei.c
fs/squashfs/squashfs.h
fs/squashfs/squashfs_fs.h
fs/squashfs/squashfs_fs_sb.h
fs/squashfs/super.c
fs/squashfs/symlink.c
fs/squashfs/zlib_wrapper.c [new file with mode: 0644]
fs/sync.c
fs/sysv/inode.c
fs/sysv/sysv.h
fs/ubifs/Kconfig
fs/ubifs/dir.c
fs/ubifs/file.c
fs/ubifs/super.c
fs/udf/balloc.c
fs/udf/file.c
fs/udf/ialloc.c
fs/udf/inode.c
fs/udf/namei.c
fs/udf/udfdecl.h
fs/ufs/balloc.c
fs/ufs/file.c
fs/ufs/ialloc.c
fs/ufs/inode.c
fs/ufs/namei.c
fs/ufs/super.c
fs/ufs/truncate.c
fs/ufs/ufs.h
fs/xfs/Makefile
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_export.c
fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_linux.h
fs/xfs/linux-2.6/xfs_lrw.c [deleted file]
fs/xfs/linux-2.6/xfs_lrw.h [deleted file]
fs/xfs/linux-2.6/xfs_quotaops.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/linux-2.6/xfs_trace.c
fs/xfs/linux-2.6/xfs_trace.h
fs/xfs/xfs_bmap.c
fs/xfs/xfs_fs.h
fs/xfs/xfs_iget.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_itable.c
fs/xfs/xfs_log.c
fs/xfs/xfs_log.h
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_trans.c
fs/xfs/xfs_trans.h
fs/xfs/xfs_trans_buf.c
fs/xfs/xfs_vnodeops.c
fs/xfs/xfs_vnodeops.h
include/asm-generic/gpio.h
include/linux/binfmts.h
include/linux/bitops.h
include/linux/coredump.h [new file with mode: 0644]
include/linux/cpumask.h
include/linux/elf.h
include/linux/elfcore.h
include/linux/exportfs.h
include/linux/ext3_fs.h
include/linux/ext3_fs_i.h
include/linux/fault-inject.h
include/linux/firmware-map.h
include/linux/fs.h
include/linux/gfp.h
include/linux/i2c/pca953x.h
include/linux/jbd.h
include/linux/jbd2.h
include/linux/kprobes.h
include/linux/kvm.h
include/linux/kvm_host.h
include/linux/list.h
include/linux/mfd/mc13783.h
include/linux/mm.h
include/linux/mm_types.h
include/linux/mmc/card.h
include/linux/mmc/host.h
include/linux/mmc/pm.h [new file with mode: 0644]
include/linux/mmc/sdio.h
include/linux/mmc/sdio_func.h
include/linux/mmzone.h
include/linux/nfs_fs.h
include/linux/nfs_fs_sb.h
include/linux/nodemask.h
include/linux/quota.h
include/linux/quotaops.h
include/linux/reiserfs_fs.h
include/linux/rmap.h
include/linux/sched.h
include/linux/slab.h
include/linux/slub_def.h
include/linux/smp.h
include/linux/spi/max7301.h
include/linux/sunrpc/bc_xprt.h
include/linux/virtio_9p.h
include/net/9p/client.h
include/trace/events/ext4.h
include/trace/events/jbd2.h
include/trace/events/kvm.h
init/initramfs.c
init/main.c
kernel/Makefile
kernel/cpu.c
kernel/elfcore.c [new file with mode: 0644]
kernel/exit.c
kernel/fork.c
kernel/kprobes.c
kernel/padata.c
kernel/panic.c
kernel/params.c
kernel/perf_event.c
kernel/pid.c
kernel/posix-cpu-timers.c
kernel/power/hibernate.c
kernel/power/suspend.c
kernel/printk.c
kernel/relay.c
kernel/sched.c
kernel/sched_cpupri.c
kernel/sched_rt.c
kernel/signal.c
kernel/sys.c
kernel/sysctl.c
kernel/tsacct.c
lib/Kconfig
lib/Kconfig.debug
lib/Makefile
lib/bitmap.c
lib/crc32.c
lib/list_sort.c
lib/show_mem.c
lib/string.c
mm/fadvise.c
mm/failslab.c
mm/filemap.c
mm/filemap_xip.c
mm/fremap.c
mm/ksm.c
mm/memcontrol.c
mm/memory-failure.c
mm/memory.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/migrate.c
mm/mlock.c
mm/mmap.c
mm/mremap.c
mm/nommu.c
mm/oom_kill.c
mm/page_alloc.c
mm/readahead.c
mm/rmap.c
mm/slab.c
mm/slub.c
mm/swap.c
mm/swapfile.c
mm/vmscan.c
mm/vmstat.c
net/9p/client.c
net/9p/protocol.c
net/9p/protocol.h
net/9p/trans_virtio.c
net/sunrpc/addr.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/svc.c
net/sunrpc/svc_xprt.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
net/sunrpc/xprtsock.c
scripts/checkpatch.pl
scripts/get_maintainer.pl
sound/soc/codecs/uda1380.c
tools/perf/Documentation/perf-probe.txt
tools/perf/Makefile
tools/perf/builtin-probe.c
tools/perf/util/probe-event.c
tools/perf/util/probe-finder.c
tools/perf/util/probe-finder.h
tools/perf/util/string.c
tools/perf/util/string.h
virt/kvm/Kconfig
virt/kvm/assigned-dev.c
virt/kvm/coalesced_mmio.c
virt/kvm/coalesced_mmio.h
virt/kvm/eventfd.c
virt/kvm/ioapic.c
virt/kvm/ioapic.h
virt/kvm/iommu.c
virt/kvm/kvm_main.c

index de6344e..efab0eb 100644 (file)
@@ -36,6 +36,7 @@ modules.builtin
 #
 tags
 TAGS
+linux
 vmlinux
 vmlinuz
 System.map
diff --git a/Documentation/ABI/stable/sysfs-devices-node b/Documentation/ABI/stable/sysfs-devices-node
new file mode 100644 (file)
index 0000000..49b82ca
--- /dev/null
@@ -0,0 +1,7 @@
+What:          /sys/devices/system/node/nodeX
+Date:          October 2002
+Contact:       Linux Memory Management list <linux-mm@kvack.org>
+Description:
+               When CONFIG_NUMA is enabled, this is a directory containing
+               information on node X such as what CPUs are local to the
+               node.
diff --git a/Documentation/fault-injection/provoke-crashes.txt b/Documentation/fault-injection/provoke-crashes.txt
new file mode 100644 (file)
index 0000000..7a9d3d8
--- /dev/null
@@ -0,0 +1,38 @@
+The lkdtm module provides an interface to crash or injure the kernel at
+predefined crashpoints to evaluate the reliability of crash dumps obtained
+using different dumping solutions. The module uses KPROBEs to instrument
+crashing points, but can also crash the kernel directly without KRPOBE
+support.
+
+
+You can provide the way either through module arguments when inserting
+the module, or through a debugfs interface.
+
+Usage: insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
+                               [cpoint_count={>0}]
+
+  recur_count : Recursion level for the stack overflow test. Default is 10.
+
+  cpoint_name : Crash point where the kernel is to be crashed. It can be
+        one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
+        FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
+        IDE_CORE_CP, DIRECT
+
+  cpoint_type : Indicates the action to be taken on hitting the crash point.
+     It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW,
+     CORRUPT_STACK, UNALIGNED_LOAD_STORE_WRITE, OVERWRITE_ALLOCATION,
+     WRITE_AFTER_FREE,
+
+  cpoint_count : Indicates the number of times the crash point is to be hit
+    to trigger an action. The default is 10.
+
+You can also induce failures by mounting debugfs and writing the type to
+<mountpoint>/provoke-crash/<crashpoint>. E.g.,
+
+  mount -t debugfs debugfs /mnt
+  echo EXCEPTION > /mnt/provoke-crash/INT_HARDWARE_ENTRY
+
+
+A special file is `DIRECT' which will induce the crash directly without
+KPROBE instrumentation. This mode is the only one available when the module
+is built on a kernel without KPROBEs support.
index 8debdd6..a5cc0db 100644 (file)
@@ -550,3 +550,35 @@ Why:       udev fully replaces this special file system that only contains CAPI
        NCCI TTY device nodes. User space (pppdcapiplugin) works without
        noticing the difference.
 Who:   Jan Kiszka <jan.kiszka@web.de>
+
+----------------------------
+
+What:  KVM memory aliases support
+When:  July 2010
+Why:   Memory aliasing support is used for speeding up guest vga access
+       through the vga windows.
+
+       Modern userspace no longer uses this feature, so it's just bitrotted
+       code and can be removed with no impact.
+Who:   Avi Kivity <avi@redhat.com>
+
+----------------------------
+
+What:  KVM kernel-allocated memory slots
+When:  July 2010
+Why:   Since 2.6.25, kvm supports user-allocated memory slots, which are
+       much more flexible than kernel-allocated slots.  All current userspace
+       supports the newer interface and this code can be removed with no
+       impact.
+Who:   Avi Kivity <avi@redhat.com>
+
+----------------------------
+
+What:  KVM paravirt mmu host support
+When:  January 2011
+Why:   The paravirt mmu host support is slower than non-paravirt mmu, both
+       on newer and older hardware.  It is already not exposed to the guest,
+       and kept only for live migration purposes.
+Who:   Avi Kivity <avi@redhat.com>
+
+----------------------------
index 18b9d0c..06bbbed 100644 (file)
@@ -460,13 +460,6 @@ in sys_read() and friends.
 
 --------------------------- dquot_operations -------------------------------
 prototypes:
-       int (*initialize) (struct inode *, int);
-       int (*drop) (struct inode *);
-       int (*alloc_space) (struct inode *, qsize_t, int);
-       int (*alloc_inode) (const struct inode *, unsigned long);
-       int (*free_space) (struct inode *, qsize_t);
-       int (*free_inode) (const struct inode *, unsigned long);
-       int (*transfer) (struct inode *, struct iattr *);
        int (*write_dquot) (struct dquot *);
        int (*acquire_dquot) (struct dquot *);
        int (*release_dquot) (struct dquot *);
@@ -479,13 +472,6 @@ a proper locking wrt the filesystem and call the generic quota operations.
 What filesystem should expect from the generic quota functions:
 
                FS recursion    Held locks when called
-initialize:    yes             maybe dqonoff_sem
-drop:          yes             -
-alloc_space:   ->mark_dirty()  -
-alloc_inode:   ->mark_dirty()  -
-free_space:    ->mark_dirty()  -
-free_inode:    ->mark_dirty()  -
-transfer:      yes             -
 write_dquot:   yes             dqonoff_sem or dqptr_sem
 acquire_dquot: yes             dqonoff_sem or dqptr_sem
 release_dquot: yes             dqonoff_sem or dqptr_sem
@@ -495,10 +481,6 @@ write_info:        yes             dqonoff_sem
 FS recursion means calling ->quota_read() and ->quota_write() from superblock
 operations.
 
-->alloc_space(), ->alloc_inode(), ->free_space(), ->free_inode() are called
-only directly by the filesystem and do not call any fs functions only
-the ->mark_dirty() operation.
-
 More details about quota locking can be found in fs/dquot.c.
 
 --------------------------- vm_operations_struct -----------------------------
index 1bd0d0c..6a53a84 100644 (file)
@@ -17,8 +17,7 @@ kernels must turn 4.1 on or off *before* turning support for version 4
 on or off; rpc.nfsd does this correctly.)
 
 The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based
-on the latest NFSv4.1 Internet Draft:
-http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29
+on RFC 5661.
 
 From the many new features in NFSv4.1 the current implementation
 focuses on the mandatory-to-implement NFSv4.1 Sessions, providing
@@ -44,7 +43,7 @@ interoperability problems with future clients.  Known issues:
          trunking, but this is a mandatory feature, and its use is
          recommended to clients in a number of places.  (E.g. to ensure
          timely renewal in case an existing connection's retry timeouts
-         have gotten too long; see section 8.3 of the draft.)
+         have gotten too long; see section 8.3 of the RFC.)
          Therefore, lack of this feature may cause future clients to
          fail.
        - Incomplete backchannel support: incomplete backchannel gss
index 0d07513..96a44dd 100644 (file)
@@ -164,6 +164,7 @@ read the file /proc/PID/status:
   VmExe:        68 kB
   VmLib:      1412 kB
   VmPTE:        20 kb
+  VmSwap:        0 kB
   Threads:        1
   SigQ:   0/28578
   SigPnd: 0000000000000000
@@ -188,6 +189,12 @@ memory usage. Its seven fields are explained in Table 1-3.  The stat file
 contains details information about the process itself.  Its fields are
 explained in Table 1-4.
 
+(for SMP CONFIG users)
+For making accounting scalable, RSS related information are handled in
+asynchronous manner and the vaule may not be very precise. To see a precise
+snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table.
+It's slow but very precise.
+
 Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
 ..............................................................................
  Field                       Content
@@ -213,6 +220,7 @@ Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
  VmExe                       size of text segment
  VmLib                       size of shared library code
  VmPTE                       size of page table entries
+ VmSwap                      size of swap usage (the number of referred swapents)
  Threads                     number of threads
  SigQ                        number of signals queued/max. number for queue
  SigPnd                      bitmap of pending signals for the thread
@@ -430,6 +438,7 @@ Table 1-5: Kernel info in /proc
  modules     List of loaded modules                            
  mounts      Mounted filesystems                               
  net         Networking info (see text)                        
+ pagetypeinfo Additional page allocator information (see text)  (2.5)
  partitions  Table of partitions known to the system           
  pci        Deprecated info of PCI bus (new way -> /proc/bus/pci/,
              decoupled by lspci                                        (2.4)
@@ -584,7 +593,7 @@ Node 0, zone      DMA      0      4      5      4      4      3 ...
 Node 0, zone   Normal      1      0      0      1    101      8 ...
 Node 0, zone  HighMem      2      0      0      1      1      0 ...
 
-Memory fragmentation is a problem under some workloads, and buddyinfo is a 
+External fragmentation is a problem under some workloads, and buddyinfo is a
 useful tool for helping diagnose these problems.  Buddyinfo will give you a 
 clue as to how big an area you can safely allocate, or why a previous
 allocation failed.
@@ -594,6 +603,48 @@ available.  In this case, there are 0 chunks of 2^0*PAGE_SIZE available in
 ZONE_DMA, 4 chunks of 2^1*PAGE_SIZE in ZONE_DMA, 101 chunks of 2^4*PAGE_SIZE 
 available in ZONE_NORMAL, etc... 
 
+More information relevant to external fragmentation can be found in
+pagetypeinfo.
+
+> cat /proc/pagetypeinfo
+Page block order: 9
+Pages per block:  512
+
+Free pages count per migrate type at order       0      1      2      3      4      5      6      7      8      9     10
+Node    0, zone      DMA, type    Unmovable      0      0      0      1      1      1      1      1      1      1      0
+Node    0, zone      DMA, type  Reclaimable      0      0      0      0      0      0      0      0      0      0      0
+Node    0, zone      DMA, type      Movable      1      1      2      1      2      1      1      0      1      0      2
+Node    0, zone      DMA, type      Reserve      0      0      0      0      0      0      0      0      0      1      0
+Node    0, zone      DMA, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
+Node    0, zone    DMA32, type    Unmovable    103     54     77      1      1      1     11      8      7      1      9
+Node    0, zone    DMA32, type  Reclaimable      0      0      2      1      0      0      0      0      1      0      0
+Node    0, zone    DMA32, type      Movable    169    152    113     91     77     54     39     13      6      1    452
+Node    0, zone    DMA32, type      Reserve      1      2      2      2      2      0      1      1      1      1      0
+Node    0, zone    DMA32, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
+
+Number of blocks type     Unmovable  Reclaimable      Movable      Reserve      Isolate
+Node 0, zone      DMA            2            0            5            1            0
+Node 0, zone    DMA32           41            6          967            2            0
+
+Fragmentation avoidance in the kernel works by grouping pages of different
+migrate types into the same contiguous regions of memory called page blocks.
+A page block is typically the size of the default hugepage size e.g. 2MB on
+X86-64. By keeping pages grouped based on their ability to move, the kernel
+can reclaim pages within a page block to satisfy a high-order allocation.
+
+The pagetypinfo begins with information on the size of a page block. It
+then gives the same type of information as buddyinfo except broken down
+by migrate-type and finishes with details on how many page blocks of each
+type exist.
+
+If min_free_kbytes has been tuned correctly (recommendations made by hugeadm
+from libhugetlbfs http://sourceforge.net/projects/libhugetlbfs/), one can
+make an estimate of the likely number of huge pages that can be allocated
+at a given point in time. All the "Movable" blocks should be allocatable
+unless memory has been mlock()'d. Some of the Reclaimable blocks should
+also be allocatable although a lot of filesystem metadata may have to be
+reclaimed to achieve this.
+
 ..............................................................................
 
 meminfo:
index 1866c27..c2c6e9b 100644 (file)
@@ -253,6 +253,70 @@ pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
 Also note that it's your responsibility to have stopped using a GPIO
 before you free it.
 
+Considering in most cases GPIOs are actually configured right after they
+are claimed, three additional calls are defined:
+
+       /* request a single GPIO, with initial configuration specified by
+        * 'flags', identical to gpio_request() wrt other arguments and
+        * return value
+        */
+       int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
+
+       /* request multiple GPIOs in a single call
+        */
+       int gpio_request_array(struct gpio *array, size_t num);
+
+       /* release multiple GPIOs in a single call
+        */
+       void gpio_free_array(struct gpio *array, size_t num);
+
+where 'flags' is currently defined to specify the following properties:
+
+       * GPIOF_DIR_IN          - to configure direction as input
+       * GPIOF_DIR_OUT         - to configure direction as output
+
+       * GPIOF_INIT_LOW        - as output, set initial level to LOW
+       * GPIOF_INIT_HIGH       - as output, set initial level to HIGH
+
+since GPIOF_INIT_* are only valid when configured as output, so group valid
+combinations as:
+
+       * GPIOF_IN              - configure as input
+       * GPIOF_OUT_INIT_LOW    - configured as output, initial level LOW
+       * GPIOF_OUT_INIT_HIGH   - configured as output, initial level HIGH
+
+In the future, these flags can be extended to support more properties such
+as open-drain status.
+
+Further more, to ease the claim/release of multiple GPIOs, 'struct gpio' is
+introduced to encapsulate all three fields as:
+
+       struct gpio {
+               unsigned        gpio;
+               unsigned long   flags;
+               const char      *label;
+       };
+
+A typical example of usage:
+
+       static struct gpio leds_gpios[] = {
+               { 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* default to ON */
+               { 33, GPIOF_OUT_INIT_LOW,  "Green LED" }, /* default to OFF */
+               { 34, GPIOF_OUT_INIT_LOW,  "Red LED"   }, /* default to OFF */
+               { 35, GPIOF_OUT_INIT_LOW,  "Blue LED"  }, /* default to OFF */
+               { ... },
+       };
+
+       err = gpio_request_one(31, GPIOF_IN, "Reset Button");
+       if (err)
+               ...
+
+       err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
+       if (err)
+               ...
+
+       gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
+
 
 GPIOs mapped to IRQs
 --------------------
diff --git a/Documentation/init.txt b/Documentation/init.txt
new file mode 100644 (file)
index 0000000..535ad5e
--- /dev/null
@@ -0,0 +1,49 @@
+Explaining the dreaded "No init found." boot hang message
+=========================================================
+
+OK, so you've got this pretty unintuitive message (currently located
+in init/main.c) and are wondering what the H*** went wrong.
+Some high-level reasons for failure (listed roughly in order of execution)
+to load the init binary are:
+A) Unable to mount root FS
+B) init binary doesn't exist on rootfs
+C) broken console device
+D) binary exists but dependencies not available
+E) binary cannot be loaded
+
+Detailed explanations:
+0) Set "debug" kernel parameter (in bootloader config file or CONFIG_CMDLINE)
+   to get more detailed kernel messages.
+A) make sure you have the correct root FS type
+   (and root= kernel parameter points to the correct partition),
+   required drivers such as storage hardware (such as SCSI or USB!)
+   and filesystem (ext3, jffs2 etc.) are builtin (alternatively as modules,
+   to be pre-loaded by an initrd)
+C) Possibly a conflict in console= setup --> initial console unavailable.
+   E.g. some serial consoles are unreliable due to serial IRQ issues (e.g.
+   missing interrupt-based configuration).
+   Try using a different console= device or e.g. netconsole= .
+D) e.g. required library dependencies of the init binary such as
+   /lib/ld-linux.so.2 missing or broken. Use readelf -d <INIT>|grep NEEDED
+   to find out which libraries are required.
+E) make sure the binary's architecture matches your hardware.
+   E.g. i386 vs. x86_64 mismatch, or trying to load x86 on ARM hardware.
+   In case you tried loading a non-binary file here (shell script?),
+   you should make sure that the script specifies an interpreter in its shebang
+   header line (#!/...) that is fully working (including its library
+   dependencies). And before tackling scripts, better first test a simple
+   non-script binary such as /bin/sh and confirm its successful execution.
+   To find out more, add code to init/main.c to display kernel_execve()s
+   return values.
+
+Please extend this explanation whenever you find new failure causes
+(after all loading the init binary is a CRITICAL and hard transition step
+which needs to be made as painless as possible), then submit patch to LKML.
+Further TODOs:
+- Implement the various run_init_process() invocations via a struct array
+  which can then store the kernel_execve() result value and on failure
+  log it all by iterating over _all_ results (very important usability fix).
+- try to make the implementation itself more helpful in general,
+  e.g. by providing additional error messages at affected places.
+
+Andreas Mohr <andi at lisas period de>
index 053037a..2f9115c 100644 (file)
@@ -1,6 +1,7 @@
 Title  : Kernel Probes (Kprobes)
 Authors        : Jim Keniston <jkenisto@us.ibm.com>
-       : Prasanna S Panchamukhi <prasanna@in.ibm.com>
+       : Prasanna S Panchamukhi <prasanna.panchamukhi@gmail.com>
+       : Masami Hiramatsu <mhiramat@redhat.com>
 
 CONTENTS
 
@@ -15,6 +16,7 @@ CONTENTS
 9. Jprobes Example
 10. Kretprobes Example
 Appendix A: The kprobes debugfs interface
+Appendix B: The kprobes sysctl interface
 
 1. Concepts: Kprobes, Jprobes, Return Probes
 
@@ -42,13 +44,13 @@ 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
-difference between a pre_handler and a post_handler, and how
-to use the maxactive and nmissed fields of a kretprobe.  But
-if you're in a hurry to start using Kprobes, you can skip ahead
-to section 2.
+The next four subsections explain how the different types of
+probes work and how jump optimization works.  They explain certain
+things that you'll need to know in order to make the best use of
+Kprobes -- e.g., the difference between a pre_handler and
+a post_handler, and how to use the maxactive and nmissed fields of
+a kretprobe.  But if you're in a hurry to start using Kprobes, you
+can skip ahead to section 2.
 
 1.1 How Does a Kprobe Work?
 
@@ -161,13 +163,125 @@ In case probed function is entered but there is no kretprobe_instance
 object available, then in addition to incrementing the nmissed count,
 the user entry_handler invocation is also skipped.
 
+1.4 How Does Jump Optimization Work?
+
+If you configured your kernel with CONFIG_OPTPROBES=y (currently
+this option is supported on x86/x86-64, non-preemptive kernel) and
+the "debug.kprobes_optimization" kernel parameter is set to 1 (see
+sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
+instruction instead of a breakpoint instruction at each probepoint.
+
+1.4.1 Init a Kprobe
+
+When a probe is registered, before attempting this optimization,
+Kprobes inserts an ordinary, breakpoint-based kprobe at the specified
+address. So, even if it's not possible to optimize this particular
+probepoint, there'll be a probe there.
+
+1.4.2 Safety Check
+
+Before optimizing a probe, Kprobes performs the following safety checks:
+
+- Kprobes verifies that the region that will be replaced by the jump
+instruction (the "optimized region") lies entirely within one function.
+(A jump instruction is multiple bytes, and so may overlay multiple
+instructions.)
+
+- Kprobes analyzes the entire function and verifies that there is no
+jump into the optimized region.  Specifically:
+  - the function contains no indirect jump;
+  - the function contains no instruction that causes an exception (since
+  the fixup code triggered by the exception could jump back into the
+  optimized region -- Kprobes checks the exception tables to verify this);
+  and
+  - there is no near jump to the optimized region (other than to the first
+  byte).
+
+- For each instruction in the optimized region, Kprobes verifies that
+the instruction can be executed out of line.
+
+1.4.3 Preparing Detour Buffer
+
+Next, Kprobes prepares a "detour" buffer, which contains the following
+instruction sequence:
+- code to push the CPU's registers (emulating a breakpoint trap)
+- a call to the trampoline code which calls user's probe handlers.
+- code to restore registers
+- the instructions from the optimized region
+- a jump back to the original execution path.
+
+1.4.4 Pre-optimization
+
+After preparing the detour buffer, Kprobes verifies that none of the
+following situations exist:
+- The probe has either a break_handler (i.e., it's a jprobe) or a
+post_handler.
+- Other instructions in the optimized region are probed.
+- The probe is disabled.
+In any of the above cases, Kprobes won't start optimizing the probe.
+Since these are temporary situations, Kprobes tries to start
+optimizing it again if the situation is changed.
+
+If the kprobe can be optimized, Kprobes enqueues the kprobe to an
+optimizing list, and kicks the kprobe-optimizer workqueue to optimize
+it.  If the to-be-optimized probepoint is hit before being optimized,
+Kprobes returns control to the original instruction path by setting
+the CPU's instruction pointer to the copied code in the detour buffer
+-- thus at least avoiding the single-step.
+
+1.4.5 Optimization
+
+The Kprobe-optimizer doesn't insert the jump instruction immediately;
+rather, it calls synchronize_sched() for safety first, because it's
+possible for a CPU to be interrupted in the middle of executing the
+optimized region(*).  As you know, synchronize_sched() can ensure
+that all interruptions that were active when synchronize_sched()
+was called are done, but only if CONFIG_PREEMPT=n.  So, this version
+of kprobe optimization supports only kernels with CONFIG_PREEMPT=n.(**)
+
+After that, the Kprobe-optimizer calls stop_machine() to replace
+the optimized region with a jump instruction to the detour buffer,
+using text_poke_smp().
+
+1.4.6 Unoptimization
+
+When an optimized kprobe is unregistered, disabled, or blocked by
+another kprobe, it will be unoptimized.  If this happens before
+the optimization is complete, the kprobe is just dequeued from the
+optimized list.  If the optimization has been done, the jump is
+replaced with the original code (except for an int3 breakpoint in
+the first byte) by using text_poke_smp().
+
+(*)Please imagine that the 2nd instruction is interrupted and then
+the optimizer replaces the 2nd instruction with the jump *address*
+while the interrupt handler is running. When the interrupt
+returns to original address, there is no valid instruction,
+and it causes an unexpected result.
+
+(**)This optimization-safety checking may be replaced with the
+stop-machine method that ksplice uses for supporting a CONFIG_PREEMPT=y
+kernel.
+
+NOTE for geeks:
+The jump optimization changes the kprobe's pre_handler behavior.
+Without optimization, the pre_handler can change the kernel's execution
+path by changing regs->ip and returning 1.  However, when the probe
+is optimized, that modification is ignored.  Thus, if you want to
+tweak the kernel's execution path, you need to suppress optimization,
+using one of the following techniques:
+- Specify an empty function for the kprobe's post_handler or break_handler.
+ or
+- Config CONFIG_OPTPROBES=n.
+ or
+- Execute 'sysctl -w debug.kprobes_optimization=n'
+
 2. Architectures Supported
 
 Kprobes, jprobes, and return probes are implemented on the following
 architectures:
 
-- i386
-- x86_64 (AMD-64, EM64T)
+- i386 (Supports jump optimization)
+- x86_64 (AMD-64, EM64T) (Supports jump optimization)
 - ppc64
 - ia64 (Does not support probes on instruction slot1.)
 - sparc64 (Return probes not yet implemented.)
@@ -193,6 +307,10 @@ it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
 so you can use "objdump -d -l vmlinux" to see the source-to-object
 code mapping.
 
+If you want to reduce probing overhead, set "Kprobes jump optimization
+support" (CONFIG_OPTPROBES) to "y". You can find this option under the
+"Kprobes" line.
+
 4. API Reference
 
 The Kprobes API includes a "register" function and an "unregister"
@@ -389,7 +507,10 @@ the probe which has been registered.
 
 Kprobes allows multiple probes at the same address.  Currently,
 however, there cannot be multiple jprobes on the same function at
-the same time.
+the same time.  Also, a probepoint for which there is a jprobe or
+a post_handler cannot be optimized.  So if you install a jprobe,
+or a kprobe with a post_handler, at an optimized probepoint, the
+probepoint will be unoptimized automatically.
 
 In general, you can install a probe anywhere in the kernel.
 In particular, you can probe interrupt handlers.  Known exceptions
@@ -453,6 +574,38 @@ reason, Kprobes doesn't support return probes (or kprobes or jprobes)
 on the x86_64 version of __switch_to(); the registration functions
 return -EINVAL.
 
+On x86/x86-64, since the Jump Optimization of Kprobes modifies
+instructions widely, there are some limitations to optimization. To
+explain it, we introduce some terminology. Imagine a 3-instruction
+sequence consisting of a two 2-byte instructions and one 3-byte
+instruction.
+
+        IA
+         |
+[-2][-1][0][1][2][3][4][5][6][7]
+        [ins1][ins2][  ins3 ]
+       [<-     DCR       ->]
+          [<- JTPR ->]
+
+ins1: 1st Instruction
+ins2: 2nd Instruction
+ins3: 3rd Instruction
+IA:  Insertion Address
+JTPR: Jump Target Prohibition Region
+DCR: Detoured Code Region
+
+The instructions in DCR are copied to the out-of-line buffer
+of the kprobe, because the bytes in DCR are replaced by
+a 5-byte jump instruction. So there are several limitations.
+
+a) The instructions in DCR must be relocatable.
+b) The instructions in DCR must not include a call instruction.
+c) JTPR must not be targeted by any jump or call instruction.
+d) DCR must not straddle the border betweeen functions.
+
+Anyway, these limitations are checked by the in-kernel instruction
+decoder, so you don't need to worry about that.
+
 6. Probe Overhead
 
 On a typical CPU in use in 2005, a kprobe hit takes 0.5 to 1.0
@@ -476,6 +629,19 @@ k = 0.49 usec; j = 0.76; r = 0.80; kr = 0.82; jr = 1.07
 ppc64: POWER5 (gr), 1656 MHz (SMT disabled, 1 virtual CPU per physical CPU)
 k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99
 
+6.1 Optimized Probe Overhead
+
+Typically, an optimized kprobe hit takes 0.07 to 0.1 microseconds to
+process. Here are sample overhead figures (in usec) for x86 architectures.
+k = unoptimized kprobe, b = boosted (single-step skipped), o = optimized kprobe,
+r = unoptimized kretprobe, rb = boosted kretprobe, ro = optimized kretprobe.
+
+i386: Intel(R) Xeon(R) E5410, 2.33GHz, 4656.90 bogomips
+k = 0.80 usec; b = 0.33; o = 0.05; r = 1.10; rb = 0.61; ro = 0.33
+
+x86-64: Intel(R) Xeon(R) E5410, 2.33GHz, 4656.90 bogomips
+k = 0.99 usec; b = 0.43; o = 0.06; r = 1.24; rb = 0.68; ro = 0.30
+
 7. TODO
 
 a. SystemTap (http://sourceware.org/systemtap): Provides a simplified
@@ -523,7 +689,8 @@ is also specified. Following columns show probe status. If the probe is on
 a virtual address that is no longer valid (module init sections, module
 virtual addresses that correspond to modules that've been unloaded),
 such probes are marked with [GONE]. If the probe is temporarily disabled,
-such probes are marked with [DISABLED].
+such probes are marked with [DISABLED]. If the probe is optimized, it is
+marked with [OPTIMIZED].
 
 /sys/kernel/debug/kprobes/enabled: Turn kprobes ON/OFF forcibly.
 
@@ -533,3 +700,19 @@ registered probes will be disarmed, till such time a "1" is echoed to this
 file. Note that this knob just disarms and arms all kprobes and doesn't
 change each probe's disabling state. This means that disabled kprobes (marked
 [DISABLED]) will be not enabled if you turn ON all kprobes by this knob.
+
+
+Appendix B: The kprobes sysctl interface
+
+/proc/sys/debug/kprobes-optimization: Turn kprobes optimization ON/OFF.
+
+When CONFIG_OPTPROBES=y, this sysctl interface appears and it provides
+a knob to globally and forcibly turn jump optimization (see section
+1.4) ON or OFF. By default, jump optimization is allowed (ON).
+If you echo "0" to this file or set "debug.kprobes_optimization" to
+0 via sysctl, all optimized probes will be unoptimized, and any new
+probes registered after that will not be optimized.  Note that this
+knob *changes* the optimized state. This means that optimized probes
+(marked [OPTIMIZED]) will be unoptimized ([OPTIMIZED] tag will be
+removed). If the knob is turned on, they will be optimized again.
+
index 2811e45..c6416a3 100644 (file)
@@ -23,12 +23,12 @@ of a virtual machine.  The ioctls belong to three classes
    Only run vcpu ioctls from the same thread that was used to create the
    vcpu.
 
-2. File descritpors
+2. File descriptors
 
 The kvm API is centered around file descriptors.  An initial
 open("/dev/kvm") obtains a handle to the kvm subsystem; this handle
 can be used to issue system ioctls.  A KVM_CREATE_VM ioctl on this
-handle will create a VM file descripror which can be used to issue VM
+handle will create a VM file descriptor which can be used to issue VM
 ioctls.  A KVM_CREATE_VCPU ioctl on a VM fd will create a virtual cpu
 and return a file descriptor pointing to it.  Finally, ioctls on a vcpu
 fd can be used to control the vcpu, including the important task of
@@ -643,7 +643,7 @@ Type: vm ioctl
 Parameters: struct kvm_clock_data (in)
 Returns: 0 on success, -1 on error
 
-Sets the current timestamp of kvmclock to the valued specific in its parameter.
+Sets the current timestamp of kvmclock to the value specified in its parameter.
 In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
 such as migration.
 
@@ -795,11 +795,11 @@ Unused.
                        __u64 data_offset; /* relative to kvm_run start */
                } io;
 
-If exit_reason is KVM_EXIT_IO_IN or KVM_EXIT_IO_OUT, then the vcpu has
+If exit_reason is KVM_EXIT_IO, then the vcpu has
 executed a port I/O instruction which could not be satisfied by kvm.
 data_offset describes where the data is located (KVM_EXIT_IO_OUT) or
 where kvm expects application code to place the data for the next
-KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a patcked array.
+KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a packed array.
 
                struct {
                        struct kvm_debug_exit_arch arch;
@@ -815,7 +815,7 @@ Unused.
                        __u8  is_write;
                } mmio;
 
-If exit_reason is KVM_EXIT_MMIO or KVM_EXIT_IO_OUT, then the vcpu has
+If exit_reason is KVM_EXIT_MMIO, then the vcpu has
 executed a memory-mapped I/O instruction which could not be satisfied
 by kvm.  The 'data' member contains the written data if 'is_write' is
 true, and should be filled by application code otherwise.
index b37300e..07375e7 100644 (file)
@@ -41,6 +41,7 @@ Possible debug options are
        P               Poisoning (object and padding)
        U               User tracking (free and alloc)
        T               Trace (please only use on single slabs)
+       A               Toggle failslab filter mark for the cache
        O               Switch debugging off for caches that would have
                        caused higher minimum slab orders
        -               Switch all debugging off (useful if the kernel is
index d6cbddb..bfa4fd1 100644 (file)
@@ -71,6 +71,7 @@ Descriptions of section entries:
        M: Mail patches to: FullName <address@domain>
        L: Mailing list that is relevant to this area
        W: Web-page with status/info
+       Q: Patchwork web based patch tracking system site
        T: SCM tree type and location.  Type is one of: git, hg, quilt, stgit.
        S: Status, one of the following:
           Supported:   Someone is actually paid to look after this.
@@ -182,6 +183,7 @@ M:  Ron Minnich <rminnich@sandia.gov>
 M:     Latchesar Ionkov <lucho@ionkov.net>
 L:     v9fs-developer@lists.sourceforge.net
 W:     http://swik.net/v9fs
+Q:     http://patchwork.kernel.org/project/v9fs-devel/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git
 S:     Maintained
 F:     Documentation/filesystems/9p.txt
@@ -238,6 +240,7 @@ ACPI
 M:     Len Brown <lenb@kernel.org>
 L:     linux-acpi@vger.kernel.org
 W:     http://www.lesswatts.org/projects/acpi/
+Q:     http://patchwork.kernel.org/project/linux-acpi/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
 S:     Supported
 F:     drivers/acpi/
@@ -428,7 +431,6 @@ P:  Jordan Crouse
 L:     linux-geode@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
 S:     Supported
-F:     arch/x86/kernel/geode_32.c
 F:     drivers/char/hw_random/geode-rng.c
 F:     drivers/crypto/geode*
 F:     drivers/video/geode/
@@ -1339,6 +1341,7 @@ BTRFS FILE SYSTEM
 M:     Chris Mason <chris.mason@oracle.com>
 L:     linux-btrfs@vger.kernel.org
 W:     http://btrfs.wiki.kernel.org/
+Q:     http://patchwork.kernel.org/project/linux-btrfs/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
 S:     Maintained
 F:     Documentation/filesystems/btrfs.txt
@@ -1503,6 +1506,7 @@ M:        Steve French <sfrench@samba.org>
 L:     linux-cifs-client@lists.samba.org (moderated for non-subscribers)
 L:     samba-technical@lists.samba.org (moderated for non-subscribers)
 W:     http://linux-cifs.samba.org/
+Q:     http://patchwork.ozlabs.org/project/linux-cifs-client/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
 S:     Supported
 F:     Documentation/filesystems/cifs.txt
@@ -1789,6 +1793,7 @@ DEVICE-MAPPER  (LVM)
 P:     Alasdair Kergon
 L:     dm-devel@redhat.com
 W:     http://sources.redhat.com/dm
+Q:     http://patchwork.kernel.org/project/dm-devel/list/
 S:     Maintained
 F:     Documentation/device-mapper/
 F:     drivers/md/dm*
@@ -2133,6 +2138,7 @@ M:        "Theodore Ts'o" <tytso@mit.edu>
 M:     Andreas Dilger <adilger@sun.com>
 L:     linux-ext4@vger.kernel.org
 W:     http://ext4.wiki.kernel.org
+Q:     http://patchwork.ozlabs.org/project/linux-ext4/list/
 S:     Maintained
 F:     Documentation/filesystems/ext4.txt
 F:     fs/ext4/
@@ -2509,13 +2515,6 @@ L:       linux-parisc@vger.kernel.org
 S:     Maintained
 F:     sound/parisc/harmony.*
 
-HAYES ESP SERIAL DRIVER
-M:     "Andrew J. Robinson" <arobinso@nyx.net>
-W:     http://www.nyx.net/~arobinso
-S:     Maintained
-F:     Documentation/serial/hayes-esp.txt
-F:     drivers/char/esp.c
-
 HEWLETT-PACKARD SMART2 RAID DRIVER
 M:     Chirag Kantharia <chirag.kantharia@hp.com>
 L:     iss_storagedev@hp.com
@@ -2724,6 +2723,7 @@ F:        drivers/scsi/ips.*
 IDE SUBSYSTEM
 M:     "David S. Miller" <davem@davemloft.net>
 L:     linux-ide@vger.kernel.org
+Q:     http://patchwork.ozlabs.org/project/linux-ide/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git
 S:     Maintained
 F:     Documentation/ide/
@@ -2778,6 +2778,7 @@ M:        Sean Hefty <sean.hefty@intel.com>
 M:     Hal Rosenstock <hal.rosenstock@gmail.com>
 L:     linux-rdma@vger.kernel.org
 W:     http://www.openib.org/
+Q:     http://patchwork.kernel.org/project/linux-rdma/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git
 S:     Supported
 F:     Documentation/infiniband/
@@ -2797,6 +2798,7 @@ INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS
 M:     Dmitry Torokhov <dmitry.torokhov@gmail.com>
 M:     Dmitry Torokhov <dtor@mail.ru>
 L:     linux-input@vger.kernel.org
+Q:     http://patchwork.kernel.org/project/linux-input/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git
 S:     Maintained
 F:     drivers/input/
@@ -3113,6 +3115,7 @@ F:        drivers/hwmon/k8temp.c
 KCONFIG
 M:     Roman Zippel <zippel@linux-m68k.org>
 L:     linux-kbuild@vger.kernel.org
+Q:     http://patchwork.kernel.org/project/linux-kbuild/list/
 S:     Maintained
 F:     Documentation/kbuild/kconfig-language.txt
 F:     scripts/kconfig/
@@ -3187,7 +3190,7 @@ F:        arch/x86/include/asm/svm.h
 F:     arch/x86/kvm/svm.c
 
 KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
-M:     Hollis Blanchard <hollisb@us.ibm.com>
+M:     Alexander Graf <agraf@suse.de>
 L:     kvm-ppc@vger.kernel.org
 W:     http://kvm.qumranet.com
 S:     Supported
@@ -3326,6 +3329,7 @@ M:        Benjamin Herrenschmidt <benh@kernel.crashing.org>
 M:     Paul Mackerras <paulus@samba.org>
 W:     http://www.penguinppc.org/
 L:     linuxppc-dev@ozlabs.org
+Q:     http://patchwork.ozlabs.org/project/linuxppc-dev/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
 S:     Supported
 F:     Documentation/powerpc/
@@ -3582,6 +3586,7 @@ M:        Mauro Carvalho Chehab <mchehab@infradead.org>
 P:     LinuxTV.org Project
 L:     linux-media@vger.kernel.org
 W:     http://linuxtv.org
+Q:     http://patchwork.kernel.org/project/linux-media/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 S:     Maintained
 F:     Documentation/dvb/
@@ -3617,8 +3622,9 @@ F:        mm/memcontrol.c
 
 MEMORY TECHNOLOGY DEVICES (MTD)
 M:     David Woodhouse <dwmw2@infradead.org>
-W:     http://www.linux-mtd.infradead.org/
 L:     linux-mtd@lists.infradead.org
+W:     http://www.linux-mtd.infradead.org/
+Q:     http://patchwork.ozlabs.org/project/linux-mtd/list/
 T:     git git://git.infradead.org/mtd-2.6.git
 S:     Maintained
 F:     drivers/mtd/
@@ -3878,6 +3884,7 @@ S:        Maintained
 NETWORKING [WIRELESS]
 M:     "John W. Linville" <linville@tuxdriver.com>
 L:     linux-wireless@vger.kernel.org
+Q:     http://patchwork.kernel.org/project/linux-wireless/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
 S:     Maintained
 F:     net/mac80211/
@@ -3970,6 +3977,7 @@ M:        Tony Lindgren <tony@atomide.com>
 L:     linux-omap@vger.kernel.org
 W:     http://www.muru.com/linux/omap/
 W:     http://linux.omap.com/
+Q:     http://patchwork.kernel.org/project/linux-omap/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
 S:     Maintained
 F:     arch/arm/*omap*/
@@ -4196,6 +4204,7 @@ M:        Helge Deller <deller@gmx.de>
 M:     "James E.J. Bottomley" <jejb@parisc-linux.org>
 L:     linux-parisc@vger.kernel.org
 W:     http://www.parisc-linux.org/
+Q:     http://patchwork.kernel.org/project/linux-parisc/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
 S:     Maintained
 F:     arch/parisc/
@@ -4238,6 +4247,7 @@ F:        Documentation/powerpc/eeh-pci-error-recovery.txt
 PCI SUBSYSTEM
 M:     Jesse Barnes <jbarnes@virtuousgeek.org>
 L:     linux-pci@vger.kernel.org
+Q:     http://patchwork.kernel.org/project/linux-pci/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
 S:     Supported
 F:     Documentation/PCI/
@@ -4279,7 +4289,9 @@ M:        Ingo Molnar <mingo@elte.hu>
 S:     Supported
 F:     kernel/perf_event.c
 F:     include/linux/perf_event.h
-F:     arch/*/*/kernel/perf_event.c
+F:     arch/*/kernel/perf_event.c
+F:     arch/*/kernel/*/perf_event.c
+F:     arch/*/kernel/*/*/perf_event.c
 F:     arch/*/include/asm/perf_event.h
 F:     arch/*/lib/perf_event.c
 F:     arch/*/kernel/perf_callchain.c
@@ -4613,6 +4625,7 @@ F:        include/linux/rtc.h
 REAL TIME CLOCK (RTC) SUBSYSTEM
 M:     Alessandro Zummo <a.zummo@towertech.it>
 L:     rtc-linux@googlegroups.com
+Q:     http://patchwork.ozlabs.org/project/rtc-linux/list/
 S:     Maintained
 F:     Documentation/rtc.txt
 F:     drivers/rtc/
@@ -4980,6 +4993,7 @@ F:        drivers/*/*/*s3c2410*
 TI DAVINCI MACHINE SUPPORT
 P:     Kevin Hilman
 M:     davinci-linux-open-source@linux.davincidsp.com
+Q:     http://patchwork.kernel.org/project/linux-davinci/list/
 S:     Supported
 F:     arch/arm/mach-davinci
 
@@ -5145,6 +5159,7 @@ F:        include/sound/soc*
 SPARC + UltraSPARC (sparc/sparc64)
 M:     "David S. Miller" <davem@davemloft.net>
 L:     sparclinux@vger.kernel.org
+Q:     http://patchwork.ozlabs.org/project/sparclinux/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
 S:     Maintained
@@ -5160,6 +5175,7 @@ SPI SUBSYSTEM
 M:     David Brownell <dbrownell@users.sourceforge.net>
 M:     Grant Likely <grant.likely@secretlab.ca>
 L:     spi-devel-general@lists.sourceforge.net
+Q:     http://patchwork.kernel.org/project/spi-devel-general/list/
 S:     Maintained
 F:     Documentation/spi/
 F:     drivers/spi/
@@ -5215,7 +5231,7 @@ F:        drivers/net/starfire*
 
 STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
 S:     Orphan
-F:     drivers/net/wireless/strip.c
+F:     drivers/staging/strip/strip.c
 F:     include/linux/if_strip.h
 
 STRADIS MPEG-2 DECODER DRIVER
@@ -5236,6 +5252,7 @@ SUPERH
 M:     Paul Mundt <lethal@linux-sh.org>
 L:     linux-sh@vger.kernel.org
 W:     http://www.linux-sh.org
+Q:     http://patchwork.kernel.org/project/linux-sh/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git
 S:     Supported
 F:     Documentation/sh/
@@ -6003,7 +6020,7 @@ L:        linux-wireless@vger.kernel.org
 W:     http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
 S:     Maintained
 F:     Documentation/networking/wavelan.txt
-F:     drivers/net/wireless/wavelan*
+F:     drivers/staging/wavelan/
 
 WD7000 SCSI DRIVER
 M:     Miroslav Zagorac <zaga@fly.cc.fer.hr>
@@ -6199,6 +6216,7 @@ F:        drivers/serial/zs.*
 THE REST
 M:     Linus Torvalds <torvalds@linux-foundation.org>
 L:     linux-kernel@vger.kernel.org
+Q:     http://patchwork.kernel.org/project/LKML/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
 S:     Buried alive in reporters
 F:     *
index 215e460..e5eb133 100644 (file)
@@ -41,6 +41,17 @@ config KPROBES
          for kernel debugging, non-intrusive instrumentation and testing.
          If in doubt, say "N".
 
+config OPTPROBES
+       bool "Kprobes jump optimization support (EXPERIMENTAL)"
+       default y
+       depends on KPROBES
+       depends on !PREEMPT
+       depends on HAVE_OPTPROBES
+       select KALLSYMS_ALL
+       help
+         This option will allow kprobes to optimize breakpoint to
+         a jump for reducing its overhead.
+
 config HAVE_EFFICIENT_UNALIGNED_ACCESS
        bool
        help
@@ -83,6 +94,8 @@ config HAVE_KPROBES
 config HAVE_KRETPROBES
        bool
 
+config HAVE_OPTPROBES
+       bool
 #
 # An arch should select this if it provides all these things:
 #
index 62619f2..53c213f 100644 (file)
@@ -361,7 +361,7 @@ osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags)
 SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
                int, flag, void __user *, data)
 {
-       int retval = -EINVAL;
+       int retval;
        char *name;
 
        name = getname(path);
@@ -379,6 +379,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
                retval = osf_procfs_mount(name, data, flag);
                break;
        default:
+               retval = -EINVAL;
                printk("osf_mount(%ld, %x)\n", typenr, flag);
        }
        putname(name);
index 7adac38..059eac6 100644 (file)
@@ -20,6 +20,12 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config GENERIC_TIME
+       def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
+       def_bool y
+
 config GENERIC_IOMAP
        bool
        default y
index fd529a0..b70fb34 100644 (file)
@@ -628,9 +628,9 @@ static int create_output_descriptors(struct cryptocop_operation *operation, int
                cdesc->dma_descr->buf = (char*)virt_to_phys(operation->tfrm_op.indata[*iniov_ix].iov_base + *iniov_offset);
                cdesc->dma_descr->after = cdesc->dma_descr->buf + dlength;
 
+               assert(desc_len >= dlength);
                desc_len -= dlength;
                *iniov_offset += dlength;
-               assert(desc_len >= 0);
                if (*iniov_offset >= operation->tfrm_op.indata[*iniov_ix].iov_len) {
                        *iniov_offset = 0;
                        ++(*iniov_ix);
index 84d31bd..82ef293 100644 (file)
@@ -332,7 +332,7 @@ int crisv32_arbiter_unwatch(int id)
        if (id == 0)
                intr_mask.bp0 = regk_marb_no;
        else if (id == 1)
-               intr_mask.bp2 = regk_marb_no;
+               intr_mask.bp1 = regk_marb_no;
        else if (id == 2)
                intr_mask.bp2 = regk_marb_no;
        else if (id == 3)
index 074fe7d..a05dd31 100644 (file)
@@ -42,75 +42,11 @@ unsigned long loops_per_usec;
 extern unsigned long do_slow_gettimeoffset(void);
 static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
 
-/*
- * This version of gettimeofday has near microsecond resolution.
- *
- * Note: Division is quite slow on CRIS and do_gettimeofday is called
- *       rather often. Maybe we should do some kind of approximation here
- *       (a naive approximation would be to divide by 1024).
- */
-void do_gettimeofday(struct timeval *tv)
-{
-       unsigned long flags;
-       signed long usec, sec;
-       local_irq_save(flags);
-       usec = do_gettimeoffset();
-
-        /*
-        * If time_adjust is negative then NTP is slowing the clock
-        * so make sure not to go into next possible interval.
-        * Better to lose some accuracy than have time go backwards..
-        */
-       if (unlikely(time_adjust < 0) && usec > tickadj)
-               usec = tickadj;
-
-       sec = xtime.tv_sec;
-       usec += xtime.tv_nsec / 1000;
-       local_irq_restore(flags);
-
-       while (usec >= 1000000) {
-               usec -= 1000000;
-               sec++;
-       }
-
-       tv->tv_sec = sec;
-       tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
+u32 arch_gettimeoffset(void)
 {
-       time_t wtm_sec, sec = tv->tv_sec;
-       long wtm_nsec, nsec = tv->tv_nsec;
-
-       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-               return -EINVAL;
-
-       write_seqlock_irq(&xtime_lock);
-       /*
-        * This is revolting. We need to set "xtime" correctly. However, the
-        * value in this location is the value at the most recent update of
-        * wall time.  Discover what correction gettimeofday() would have
-        * made, and then undo it!
-        */
-       nsec -= do_gettimeoffset() * NSEC_PER_USEC;
-
-       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-       set_normalized_timespec(&xtime, sec, nsec);
-       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-       ntp_clear();
-       write_sequnlock_irq(&xtime_lock);
-       clock_was_set();
-       return 0;
+       return do_gettimeoffset() * 1000;
 }
 
-EXPORT_SYMBOL(do_settimeofday);
-
-
 /*
  * BUG: This routine does not handle hour overflow properly; it just
  *      sets the minutes. Usually you'll only notice that after reboot!
index 492b5c4..8c7260a 100644 (file)
@@ -68,41 +68,4 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 #define PCIBIOS_MIN_IO         0x100
 #define PCIBIOS_MIN_MEM                0x00010000
 
-/* Make physical memory consistent for a single
- * streaming mode DMA translation after a transfer.
- *
- * If you perform a pci_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so.  At the
- * next point you give the PCI dma address back to the card, the
- * device again owns the buffer.
- */
-static inline void pci_dma_sync_single(struct pci_dev *hwdev,
-                                      dma_addr_t dma_handle,
-                                      size_t size, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-
-       frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle),
-                           (unsigned long)bus_to_virt(dma_handle) + size);
-}
-
-/* Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as pci_dma_sync_single but for a scatter-gather list,
- * same rules and usage.
- */
-static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
-                                  struct scatterlist *sg,
-                                  int nelems, int direction)
-{
-       int i;
-       BUG_ON(direction == PCI_DMA_NONE);
-
-       for (i = 0; i < nelems; i++)
-               frv_cache_wback_inv(sg_dma_address(&sg[i]),
-                                   sg_dma_address(&sg[i])+sg_dma_len(&sg[i]));
-}
-
 #endif /* _ASM_FRV_PCI_H */
index 4c41656..b5298eb 100644 (file)
@@ -219,54 +219,6 @@ do {                                                                               \
        NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR);                \
 } while (0)
 
-
-/*
- * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
- * extra segments containing the gate DSO contents.  Dumping its
- * contents makes post-mortem fully interpretable later without matching up
- * the same kernel and hardware config to see what PC values meant.
- * Dumping its extra ELF program headers includes all the other information
- * a debugger needs to easily find how the gate DSO was being used.
- */
-#define ELF_CORE_EXTRA_PHDRS           (GATE_EHDR->e_phnum)
-#define ELF_CORE_WRITE_EXTRA_PHDRS                                             \
-do {                                                                           \
-       const struct elf_phdr *const gate_phdrs =                             \
-               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);   \
-       int i;                                                                  \
-       Elf64_Off ofs = 0;                                                    \
-       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {                              \
-               struct elf_phdr phdr = gate_phdrs[i];                         \
-               if (phdr.p_type == PT_LOAD) {                                   \
-                       phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);              \
-                       phdr.p_filesz = phdr.p_memsz;                         \
-                       if (ofs == 0) {                                       \
-                               ofs = phdr.p_offset = offset;                 \
-                       offset += phdr.p_filesz;                                \
-               }                                                             \
-               else                                                          \
-                               phdr.p_offset = ofs;                          \
-               }                                                             \
-               else                                                          \
-                       phdr.p_offset += ofs;                                   \
-               phdr.p_paddr = 0; /* match other core phdrs */                  \
-               DUMP_WRITE(&phdr, sizeof(phdr));                                \
-       }                                                                       \
-} while (0)
-#define ELF_CORE_WRITE_EXTRA_DATA                                      \
-do {                                                                   \
-       const struct elf_phdr *const gate_phdrs =                             \
-               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);   \
-       int i;                                                          \
-       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {                      \
-               if (gate_phdrs[i].p_type == PT_LOAD) {                        \
-                       DUMP_WRITE((void *) gate_phdrs[i].p_vaddr,            \
-                                  PAGE_ALIGN(gate_phdrs[i].p_memsz));        \
-                       break;                                                \
-               }                                                             \
-       }                                                               \
-} while (0)
-
 /*
  * format for entries in the Global Offset Table
  */
index 4138282..db10b1e 100644 (file)
@@ -45,6 +45,8 @@ endif
 obj-$(CONFIG_DMAR)             += pci-dma.o
 obj-$(CONFIG_SWIOTLB)          += pci-swiotlb.o
 
+obj-$(CONFIG_BINFMT_ELF)       += elfcore.o
+
 # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
 CFLAGS_traps.o  += -mfixed-range=f2-f5,f16-f31
 
diff --git a/arch/ia64/kernel/elfcore.c b/arch/ia64/kernel/elfcore.c
new file mode 100644 (file)
index 0000000..bac1639
--- /dev/null
@@ -0,0 +1,80 @@
+#include <linux/elf.h>
+#include <linux/coredump.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf64_Half elf_core_extra_phdrs(void)
+{
+       return GATE_EHDR->e_phnum;
+}
+
+int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+                              unsigned long limit)
+{
+       const struct elf_phdr *const gate_phdrs =
+               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+       int i;
+       Elf64_Off ofs = 0;
+
+       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+               struct elf_phdr phdr = gate_phdrs[i];
+
+               if (phdr.p_type == PT_LOAD) {
+                       phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);
+                       phdr.p_filesz = phdr.p_memsz;
+                       if (ofs == 0) {
+                               ofs = phdr.p_offset = offset;
+                               offset += phdr.p_filesz;
+                       } else {
+                               phdr.p_offset = ofs;
+                       }
+               } else {
+                       phdr.p_offset += ofs;
+               }
+               phdr.p_paddr = 0; /* match other core phdrs */
+               *size += sizeof(phdr);
+               if (*size > limit || !dump_write(file, &phdr, sizeof(phdr)))
+                       return 0;
+       }
+       return 1;
+}
+
+int elf_core_write_extra_data(struct file *file, size_t *size,
+                             unsigned long limit)
+{
+       const struct elf_phdr *const gate_phdrs =
+               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+       int i;
+
+       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+               if (gate_phdrs[i].p_type == PT_LOAD) {
+                       void *addr = (void *)gate_phdrs[i].p_vaddr;
+                       size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz);
+
+                       *size += memsz;
+                       if (*size > limit || !dump_write(file, addr, memsz))
+                               return 0;
+                       break;
+               }
+       }
+       return 1;
+}
+
+size_t elf_core_extra_data_size(void)
+{
+       const struct elf_phdr *const gate_phdrs =
+               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+       int i;
+       size_t size = 0;
+
+       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+               if (gate_phdrs[i].p_type == PT_LOAD) {
+                       size += PAGE_ALIGN(gate_phdrs[i].p_memsz);
+                       break;
+               }
+       }
+       return size;
+}
index b81e46b..703062c 100644 (file)
@@ -2315,6 +2315,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
                DPRINT(("Cannot allocate vma\n"));
                goto error_kmem;
        }
+       INIT_LIST_HEAD(&vma->anon_vma_chain);
 
        /*
         * partially initialize the vma for the sampling buffer
index 01c7579..fa4d1e5 100644 (file)
@@ -26,6 +26,7 @@ config KVM
        select ANON_INODES
        select HAVE_KVM_IRQCHIP
        select KVM_APIC_ARCHITECTURE
+       select KVM_MMIO
        ---help---
          Support hosting fully virtualized guest machines using hardware
          virtualization extensions.  You will need a fairly recent
index 5fdeec5..26e0e08 100644 (file)
@@ -241,10 +241,10 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        return 0;
 mmio:
        if (p->dir)
-               r = kvm_io_bus_read(&vcpu->kvm->mmio_bus, p->addr,
+               r = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, p->addr,
                                    p->size, &p->data);
        else
-               r = kvm_io_bus_write(&vcpu->kvm->mmio_bus, p->addr,
+               r = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, p->addr,
                                     p->size, &p->data);
        if (r)
                printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr);
@@ -636,12 +636,9 @@ static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu)
 static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
        union context *host_ctx, *guest_ctx;
-       int r;
+       int r, idx;
 
-       /*
-        * down_read() may sleep and return with interrupts enabled
-        */
-       down_read(&vcpu->kvm->slots_lock);
+       idx = srcu_read_lock(&vcpu->kvm->srcu);
 
 again:
        if (signal_pending(current)) {
@@ -663,7 +660,7 @@ again:
        if (r < 0)
                goto vcpu_run_fail;
 
-       up_read(&vcpu->kvm->slots_lock);
+       srcu_read_unlock(&vcpu->kvm->srcu, idx);
        kvm_guest_enter();
 
        /*
@@ -687,7 +684,7 @@ again:
        kvm_guest_exit();
        preempt_enable();
 
-       down_read(&vcpu->kvm->slots_lock);
+       idx = srcu_read_lock(&vcpu->kvm->srcu);
 
        r = kvm_handle_exit(kvm_run, vcpu);
 
@@ -697,10 +694,10 @@ again:
        }
 
 out:
-       up_read(&vcpu->kvm->slots_lock);
+       srcu_read_unlock(&vcpu->kvm->srcu, idx);
        if (r > 0) {
                kvm_resched(vcpu);
-               down_read(&vcpu->kvm->slots_lock);
+               idx = srcu_read_lock(&vcpu->kvm->srcu);
                goto again;
        }
 
@@ -971,7 +968,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
                        goto out;
                r = kvm_setup_default_irq_routing(kvm);
                if (r) {
-                       kfree(kvm->arch.vioapic);
+                       kvm_ioapic_destroy(kvm);
                        goto out;
                }
                break;
@@ -1377,12 +1374,14 @@ static void free_kvm(struct kvm *kvm)
 
 static void kvm_release_vm_pages(struct kvm *kvm)
 {
+       struct kvm_memslots *slots;
        struct kvm_memory_slot *memslot;
        int i, j;
        unsigned long base_gfn;
 
-       for (i = 0; i < kvm->nmemslots; i++) {
-               memslot = &kvm->memslots[i];
+       slots = rcu_dereference(kvm->memslots);
+       for (i = 0; i < slots->nmemslots; i++) {
+               memslot = &slots->memslots[i];
                base_gfn = memslot->base_gfn;
 
                for (j = 0; j < memslot->npages; j++) {
@@ -1405,6 +1404,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
        kfree(kvm->arch.vioapic);
        kvm_release_vm_pages(kvm);
        kvm_free_physmem(kvm);
+       cleanup_srcu_struct(&kvm->srcu);
        free_kvm(kvm);
 }
 
@@ -1576,15 +1576,15 @@ out:
        return r;
 }
 
-int kvm_arch_set_memory_region(struct kvm *kvm,
-               struct kvm_userspace_memory_region *mem,
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+               struct kvm_memory_slot *memslot,
                struct kvm_memory_slot old,
+               struct kvm_userspace_memory_region *mem,
                int user_alloc)
 {
        unsigned long i;
        unsigned long pfn;
-       int npages = mem->memory_size >> PAGE_SHIFT;
-       struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot];
+       int npages = memslot->npages;
        unsigned long base_gfn = memslot->base_gfn;
 
        if (base_gfn + npages > (KVM_MAX_MEM_SIZE >> PAGE_SHIFT))
@@ -1608,6 +1608,14 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
        return 0;
 }
 
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+               struct kvm_userspace_memory_region *mem,
+               struct kvm_memory_slot old,
+               int user_alloc)
+{
+       return;
+}
+
 void kvm_arch_flush_shadow(struct kvm *kvm)
 {
        kvm_flush_remote_tlbs(kvm);
@@ -1802,7 +1810,7 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
        if (log->slot >= KVM_MEMORY_SLOTS)
                goto out;
 
-       memslot = &kvm->memslots[log->slot];
+       memslot = &kvm->memslots->memslots[log->slot];
        r = -ENOENT;
        if (!memslot->dirty_bitmap)
                goto out;
@@ -1827,6 +1835,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        struct kvm_memory_slot *memslot;
        int is_dirty = 0;
 
+       mutex_lock(&kvm->slots_lock);
        spin_lock(&kvm->arch.dirty_log_lock);
 
        r = kvm_ia64_sync_dirty_log(kvm, log);
@@ -1840,12 +1849,13 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        /* If nothing is dirty, don't bother messing with page tables. */
        if (is_dirty) {
                kvm_flush_remote_tlbs(kvm);
-               memslot = &kvm->memslots[log->slot];
+               memslot = &kvm->memslots->memslots[log->slot];
                n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
                memset(memslot->dirty_bitmap, 0, n);
        }
        r = 0;
 out:
+       mutex_unlock(&kvm->slots_lock);
        spin_unlock(&kvm->arch.dirty_log_lock);
        return r;
 }
index e4b8231..cb548ee 100644 (file)
@@ -75,7 +75,7 @@ static void set_pal_result(struct kvm_vcpu *vcpu,
        struct exit_ctl_data *p;
 
        p = kvm_get_exit_data(vcpu);
-       if (p && p->exit_reason == EXIT_REASON_PAL_CALL) {
+       if (p->exit_reason == EXIT_REASON_PAL_CALL) {
                p->u.pal_data.ret = result;
                return ;
        }
@@ -87,7 +87,7 @@ static void set_sal_result(struct kvm_vcpu *vcpu,
        struct exit_ctl_data *p;
 
        p = kvm_get_exit_data(vcpu);
-       if (p && p->exit_reason == EXIT_REASON_SAL_CALL) {
+       if (p->exit_reason == EXIT_REASON_SAL_CALL) {
                p->u.sal_data.ret = result;
                return ;
        }
@@ -322,7 +322,7 @@ static  u64 kvm_get_pal_call_index(struct kvm_vcpu *vcpu)
        struct exit_ctl_data *p;
 
        p = kvm_get_exit_data(vcpu);
-       if (p && (p->exit_reason == EXIT_REASON_PAL_CALL))
+       if (p->exit_reason == EXIT_REASON_PAL_CALL)
                index = p->u.pal_data.gr28;
 
        return index;
@@ -646,18 +646,16 @@ static void kvm_get_sal_call_data(struct kvm_vcpu *vcpu, u64 *in0, u64 *in1,
 
        p = kvm_get_exit_data(vcpu);
 
-       if (p) {
-               if (p->exit_reason == EXIT_REASON_SAL_CALL) {
-                       *in0 = p->u.sal_data.in0;
-                       *in1 = p->u.sal_data.in1;
-                       *in2 = p->u.sal_data.in2;
-                       *in3 = p->u.sal_data.in3;
-                       *in4 = p->u.sal_data.in4;
-                       *in5 = p->u.sal_data.in5;
-                       *in6 = p->u.sal_data.in6;
-                       *in7 = p->u.sal_data.in7;
-                       return ;
-               }
+       if (p->exit_reason == EXIT_REASON_SAL_CALL) {
+               *in0 = p->u.sal_data.in0;
+               *in1 = p->u.sal_data.in1;
+               *in2 = p->u.sal_data.in2;
+               *in3 = p->u.sal_data.in3;
+               *in4 = p->u.sal_data.in4;
+               *in5 = p->u.sal_data.in5;
+               *in6 = p->u.sal_data.in6;
+               *in7 = p->u.sal_data.in7;
+               return ;
        }
        *in0 = 0;
 }
index 9bf55af..fb8f9f5 100644 (file)
@@ -316,8 +316,8 @@ void emulate_io_inst(struct kvm_vcpu *vcpu, u64 padr, u64 ma)
                return;
        } else {
                inst_type = -1;
-               panic_vm(vcpu, "Unsupported MMIO access instruction! \
-                               Bunld[0]=0x%lx, Bundle[1]=0x%lx\n",
+               panic_vm(vcpu, "Unsupported MMIO access instruction! "
+                               "Bunld[0]=0x%lx, Bundle[1]=0x%lx\n",
                                bundle.i64[0], bundle.i64[1]);
        }
 
index dce75b7..958815c 100644 (file)
@@ -1639,8 +1639,8 @@ void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val)
         * Otherwise panic
         */
        if (val & (IA64_PSR_PK | IA64_PSR_IS | IA64_PSR_VM))
-               panic_vm(vcpu, "Only support guests with vpsr.pk =0 \
-                               & vpsr.is=0\n");
+               panic_vm(vcpu, "Only support guests with vpsr.pk =0 "
+                               "& vpsr.is=0\n");
 
        /*
         * For those IA64_PSR bits: id/da/dd/ss/ed/ia
index ca3335e..ed41759 100644 (file)
@@ -117,6 +117,7 @@ ia64_init_addr_space (void)
         */
        vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
        if (vma) {
+               INIT_LIST_HEAD(&vma->anon_vma_chain);
                vma->vm_mm = current->mm;
                vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
                vma->vm_end = vma->vm_start + PAGE_SIZE;
@@ -135,6 +136,7 @@ ia64_init_addr_space (void)
        if (!(current->personality & MMAP_PAGE_ZERO)) {
                vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
                if (vma) {
+                       INIT_LIST_HEAD(&vma->anon_vma_chain);
                        vma->vm_mm = current->mm;
                        vma->vm_end = PAGE_SIZE;
                        vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
index af2abe7..aadf2dd 100644 (file)
 #define RESUME_HOST             RESUME_FLAG_HOST
 #define RESUME_HOST_NV          (RESUME_FLAG_HOST|RESUME_FLAG_NV)
 
+#define KVM_GUEST_MODE_NONE    0
+#define KVM_GUEST_MODE_GUEST   1
+#define KVM_GUEST_MODE_SKIP    2
+
+#define KVM_INST_FETCH_FAILED  -1
+
 #endif /* __POWERPC_KVM_ASM_H__ */
index 74b7369..db7db0a 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <linux/types.h>
 #include <linux/kvm_host.h>
-#include <asm/kvm_ppc.h>
+#include <asm/kvm_book3s_64_asm.h>
 
 struct kvmppc_slb {
        u64 esid;
@@ -33,7 +33,8 @@ struct kvmppc_slb {
        bool Ks;
        bool Kp;
        bool nx;
-       bool large;
+       bool large;     /* PTEs are 16MB */
+       bool tb;        /* 1TB segment */
        bool class;
 };
 
@@ -69,6 +70,7 @@ struct kvmppc_sid_map {
 
 struct kvmppc_vcpu_book3s {
        struct kvm_vcpu vcpu;
+       struct kvmppc_book3s_shadow_vcpu shadow_vcpu;
        struct kvmppc_sid_map sid_map[SID_MAP_NUM];
        struct kvmppc_slb slb[64];
        struct {
@@ -89,6 +91,7 @@ struct kvmppc_vcpu_book3s {
        u64 vsid_next;
        u64 vsid_max;
        int context_id;
+       ulong prog_flags; /* flags to inject when giving a 700 trap */
 };
 
 #define CONTEXT_HOST           0
@@ -119,6 +122,10 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
 
 extern u32 kvmppc_trampoline_lowmem;
 extern u32 kvmppc_trampoline_enter;
+extern void kvmppc_rmcall(ulong srr0, ulong srr1);
+extern void kvmppc_load_up_fpu(void);
+extern void kvmppc_load_up_altivec(void);
+extern void kvmppc_load_up_vsx(void);
 
 static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
 {
index 2e06ee8..183461b 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __ASM_KVM_BOOK3S_ASM_H__
 #define __ASM_KVM_BOOK3S_ASM_H__
 
+#ifdef __ASSEMBLY__
+
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 
 #include <asm/kvm_asm.h>
@@ -55,4 +57,20 @@ kvmppc_resume_\intno:
 
 #endif /* CONFIG_KVM_BOOK3S_64_HANDLER */
 
+#else  /*__ASSEMBLY__ */
+
+struct kvmppc_book3s_shadow_vcpu {
+       ulong gpr[14];
+       u32 cr;
+       u32 xer;
+       ulong host_r1;
+       ulong host_r2;
+       ulong handler;
+       ulong scratch0;
+       ulong scratch1;
+       ulong vmhandler;
+};
+
+#endif /*__ASSEMBLY__ */
+
 #endif /* __ASM_KVM_BOOK3S_ASM_H__ */
index 9d497ce..7fea26f 100644 (file)
@@ -52,9 +52,12 @@ struct kvmppc_vcpu_e500 {
        u32 mas5;
        u32 mas6;
        u32 mas7;
+       u32 l1csr0;
        u32 l1csr1;
        u32 hid0;
        u32 hid1;
+       u32 tlb0cfg;
+       u32 tlb1cfg;
 
        struct kvm_vcpu vcpu;
 };
index 1201f62..5e5bae7 100644 (file)
@@ -167,23 +167,40 @@ struct kvm_vcpu_arch {
        ulong trampoline_lowmem;
        ulong trampoline_enter;
        ulong highmem_handler;
+       ulong rmcall;
        ulong host_paca_phys;
        struct kvmppc_mmu mmu;
 #endif
 
-       u64 fpr[32];
        ulong gpr[32];
 
+       u64 fpr[32];
+       u32 fpscr;
+
+#ifdef CONFIG_ALTIVEC
+       vector128 vr[32];
+       vector128 vscr;
+#endif
+
+#ifdef CONFIG_VSX
+       u64 vsr[32];
+#endif
+
        ulong pc;
-       u32 cr;
        ulong ctr;
        ulong lr;
+
+#ifdef CONFIG_BOOKE
        ulong xer;
+       u32 cr;
+#endif
 
        ulong msr;
 #ifdef CONFIG_PPC64
        ulong shadow_msr;
+       ulong shadow_srr1;
        ulong hflags;
+       ulong guest_owned_ext;
 #endif
        u32 mmucr;
        ulong sprg0;
@@ -242,6 +259,8 @@ struct kvm_vcpu_arch {
 #endif
        ulong fault_dear;
        ulong fault_esr;
+       ulong queued_dear;
+       ulong queued_esr;
        gpa_t paddr_accessed;
 
        u8 io_gpr; /* GPR used as IO source/target */
index 269ee46..e264282 100644 (file)
@@ -28,6 +28,9 @@
 #include <linux/types.h>
 #include <linux/kvm_types.h>
 #include <linux/kvm_host.h>
+#ifdef CONFIG_PPC_BOOK3S
+#include <asm/kvm_book3s.h>
+#endif
 
 enum emulation_result {
        EMULATE_DONE,         /* no further processing */
@@ -80,8 +83,9 @@ extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
 
 extern void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu);
 extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);
-extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu);
+extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags);
 extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
+extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
 extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
                                        struct kvm_interrupt *irq);
 
@@ -95,4 +99,81 @@ extern void kvmppc_booke_exit(void);
 
 extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu);
 
+#ifdef CONFIG_PPC_BOOK3S
+
+/* We assume we're always acting on the current vcpu */
+
+static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
+{
+       if ( num < 14 ) {
+               get_paca()->shadow_vcpu.gpr[num] = val;
+               to_book3s(vcpu)->shadow_vcpu.gpr[num] = val;
+       } else
+               vcpu->arch.gpr[num] = val;
+}
+
+static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num)
+{
+       if ( num < 14 )
+               return get_paca()->shadow_vcpu.gpr[num];
+       else
+               return vcpu->arch.gpr[num];
+}
+
+static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val)
+{
+       get_paca()->shadow_vcpu.cr = val;
+       to_book3s(vcpu)->shadow_vcpu.cr = val;
+}
+
+static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
+{
+       return get_paca()->shadow_vcpu.cr;
+}
+
+static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
+{
+       get_paca()->shadow_vcpu.xer = val;
+       to_book3s(vcpu)->shadow_vcpu.xer = val;
+}
+
+static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
+{
+       return get_paca()->shadow_vcpu.xer;
+}
+
+#else
+
+static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
+{
+       vcpu->arch.gpr[num] = val;
+}
+
+static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num)
+{
+       return vcpu->arch.gpr[num];
+}
+
+static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val)
+{
+       vcpu->arch.cr = val;
+}
+
+static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.cr;
+}
+
+static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
+{
+       vcpu->arch.xer = val;
+}
+
+static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.xer;
+}
+
+#endif
+
 #endif /* __POWERPC_KVM_PPC_H__ */
index 5e9b4ef..d8a6931 100644 (file)
@@ -19,6 +19,9 @@
 #include <asm/mmu.h>
 #include <asm/page.h>
 #include <asm/exception-64e.h>
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+#include <asm/kvm_book3s_64_asm.h>
+#endif
 
 register struct paca_struct *local_paca asm("r13");
 
@@ -135,6 +138,8 @@ struct paca_struct {
                u64     esid;
                u64     vsid;
        } kvm_slb[64];                  /* guest SLB */
+       /* We use this to store guest state in */
+       struct kvmppc_book3s_shadow_vcpu shadow_vcpu;
        u8 kvm_slb_max;                 /* highest used guest slb entry */
        u8 kvm_in_guest;                /* are we inside the guest? */
 #endif
index bc8dd53..5572e86 100644 (file)
 #define   SRR1_WAKEMT          0x00280000 /* mtctrl */
 #define   SRR1_WAKEDEC         0x00180000 /* Decrementer interrupt */
 #define   SRR1_WAKETHERM       0x00100000 /* Thermal management interrupt */
+#define   SRR1_PROGFPE         0x00100000 /* Floating Point Enabled */
+#define   SRR1_PROGPRIV                0x00040000 /* Privileged instruction */
+#define   SRR1_PROGTRAP                0x00020000 /* Trap */
+#define   SRR1_PROGADDR                0x00010000 /* SRR0 contains subsequent addr */
 #define SPRN_HSRR0     0x13A   /* Save/Restore Register 0 */
 #define SPRN_HSRR1     0x13B   /* Save/Restore Register 1 */
 
index a6c2b63..957ceb7 100644 (file)
@@ -194,6 +194,30 @@ int main(void)
        DEFINE(PACA_KVM_IN_GUEST, offsetof(struct paca_struct, kvm_in_guest));
        DEFINE(PACA_KVM_SLB, offsetof(struct paca_struct, kvm_slb));
        DEFINE(PACA_KVM_SLB_MAX, offsetof(struct paca_struct, kvm_slb_max));
+       DEFINE(PACA_KVM_CR, offsetof(struct paca_struct, shadow_vcpu.cr));
+       DEFINE(PACA_KVM_XER, offsetof(struct paca_struct, shadow_vcpu.xer));
+       DEFINE(PACA_KVM_R0, offsetof(struct paca_struct, shadow_vcpu.gpr[0]));
+       DEFINE(PACA_KVM_R1, offsetof(struct paca_struct, shadow_vcpu.gpr[1]));
+       DEFINE(PACA_KVM_R2, offsetof(struct paca_struct, shadow_vcpu.gpr[2]));
+       DEFINE(PACA_KVM_R3, offsetof(struct paca_struct, shadow_vcpu.gpr[3]));
+       DEFINE(PACA_KVM_R4, offsetof(struct paca_struct, shadow_vcpu.gpr[4]));
+       DEFINE(PACA_KVM_R5, offsetof(struct paca_struct, shadow_vcpu.gpr[5]));
+       DEFINE(PACA_KVM_R6, offsetof(struct paca_struct, shadow_vcpu.gpr[6]));
+       DEFINE(PACA_KVM_R7, offsetof(struct paca_struct, shadow_vcpu.gpr[7]));
+       DEFINE(PACA_KVM_R8, offsetof(struct paca_struct, shadow_vcpu.gpr[8]));
+       DEFINE(PACA_KVM_R9, offsetof(struct paca_struct, shadow_vcpu.gpr[9]));
+       DEFINE(PACA_KVM_R10, offsetof(struct paca_struct, shadow_vcpu.gpr[10]));
+       DEFINE(PACA_KVM_R11, offsetof(struct paca_struct, shadow_vcpu.gpr[11]));
+       DEFINE(PACA_KVM_R12, offsetof(struct paca_struct, shadow_vcpu.gpr[12]));
+       DEFINE(PACA_KVM_R13, offsetof(struct paca_struct, shadow_vcpu.gpr[13]));
+       DEFINE(PACA_KVM_HOST_R1, offsetof(struct paca_struct, shadow_vcpu.host_r1));
+       DEFINE(PACA_KVM_HOST_R2, offsetof(struct paca_struct, shadow_vcpu.host_r2));
+       DEFINE(PACA_KVM_VMHANDLER, offsetof(struct paca_struct,
+                                           shadow_vcpu.vmhandler));
+       DEFINE(PACA_KVM_SCRATCH0, offsetof(struct paca_struct,
+                                          shadow_vcpu.scratch0));
+       DEFINE(PACA_KVM_SCRATCH1, offsetof(struct paca_struct,
+                                          shadow_vcpu.scratch1));
 #endif
 #endif /* CONFIG_PPC64 */
 
@@ -389,8 +413,6 @@ int main(void)
        DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
        DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
        DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
-       DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
-       DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
        DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr));
        DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc));
        DEFINE(VCPU_MSR, offsetof(struct kvm_vcpu, arch.msr));
@@ -411,11 +433,16 @@ int main(void)
        DEFINE(VCPU_HOST_R2, offsetof(struct kvm_vcpu, arch.host_r2));
        DEFINE(VCPU_HOST_MSR, offsetof(struct kvm_vcpu, arch.host_msr));
        DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr));
+       DEFINE(VCPU_SHADOW_SRR1, offsetof(struct kvm_vcpu, arch.shadow_srr1));
        DEFINE(VCPU_TRAMPOLINE_LOWMEM, offsetof(struct kvm_vcpu, arch.trampoline_lowmem));
        DEFINE(VCPU_TRAMPOLINE_ENTER, offsetof(struct kvm_vcpu, arch.trampoline_enter));
        DEFINE(VCPU_HIGHMEM_HANDLER, offsetof(struct kvm_vcpu, arch.highmem_handler));
+       DEFINE(VCPU_RMCALL, offsetof(struct kvm_vcpu, arch.rmcall));
        DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags));
-#endif
+#else
+       DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
+       DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
+#endif /* CONFIG_PPC64 */
 #endif
 #ifdef CONFIG_44x
        DEFINE(PGD_T_LOG2, PGD_T_LOG2);
index 4254514..ab3e392 100644 (file)
@@ -107,6 +107,7 @@ EXPORT_SYMBOL(giveup_altivec);
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_VSX
 EXPORT_SYMBOL(giveup_vsx);
+EXPORT_SYMBOL_GPL(__giveup_vsx);
 #endif /* CONFIG_VSX */
 #ifdef CONFIG_SPE
 EXPORT_SYMBOL(giveup_spe);
index 61af58f..65ea083 100644 (file)
@@ -65,13 +65,14 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                         */
                        switch (dcrn) {
                        case DCRN_CPR0_CONFIG_ADDR:
-                               vcpu->arch.gpr[rt] = vcpu->arch.cpr0_cfgaddr;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.cpr0_cfgaddr);
                                break;
                        case DCRN_CPR0_CONFIG_DATA:
                                local_irq_disable();
                                mtdcr(DCRN_CPR0_CONFIG_ADDR,
                                          vcpu->arch.cpr0_cfgaddr);
-                               vcpu->arch.gpr[rt] = mfdcr(DCRN_CPR0_CONFIG_DATA);
+                               kvmppc_set_gpr(vcpu, rt,
+                                              mfdcr(DCRN_CPR0_CONFIG_DATA));
                                local_irq_enable();
                                break;
                        default:
@@ -93,11 +94,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        /* emulate some access in kernel */
                        switch (dcrn) {
                        case DCRN_CPR0_CONFIG_ADDR:
-                               vcpu->arch.cpr0_cfgaddr = vcpu->arch.gpr[rs];
+                               vcpu->arch.cpr0_cfgaddr = kvmppc_get_gpr(vcpu, rs);
                                break;
                        default:
                                run->dcr.dcrn = dcrn;
-                               run->dcr.data = vcpu->arch.gpr[rs];
+                               run->dcr.data = kvmppc_get_gpr(vcpu, rs);
                                run->dcr.is_write = 1;
                                vcpu->arch.dcr_needed = 1;
                                kvmppc_account_exit(vcpu, DCR_EXITS);
@@ -146,13 +147,13 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 
        switch (sprn) {
        case SPRN_PID:
-               kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break;
+               kvmppc_set_pid(vcpu, kvmppc_get_gpr(vcpu, rs)); break;
        case SPRN_MMUCR:
-               vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.mmucr = kvmppc_get_gpr(vcpu, rs); break;
        case SPRN_CCR0:
-               vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.ccr0 = kvmppc_get_gpr(vcpu, rs); break;
        case SPRN_CCR1:
-               vcpu->arch.ccr1 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.ccr1 = kvmppc_get_gpr(vcpu, rs); break;
        default:
                emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
        }
@@ -167,13 +168,13 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
 
        switch (sprn) {
        case SPRN_PID:
-               vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.pid); break;
        case SPRN_MMUCR:
-               vcpu->arch.gpr[rt] = vcpu->arch.mmucr; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.mmucr); break;
        case SPRN_CCR0:
-               vcpu->arch.gpr[rt] = vcpu->arch.ccr0; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr0); break;
        case SPRN_CCR1:
-               vcpu->arch.gpr[rt] = vcpu->arch.ccr1; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr1); break;
        default:
                emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
        }
index ff3cb63..2570fcc 100644 (file)
@@ -439,7 +439,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
        struct kvmppc_44x_tlbe *tlbe;
        unsigned int gtlb_index;
 
-       gtlb_index = vcpu->arch.gpr[ra];
+       gtlb_index = kvmppc_get_gpr(vcpu, ra);
        if (gtlb_index > KVM44x_GUEST_TLB_SIZE) {
                printk("%s: index %d\n", __func__, gtlb_index);
                kvmppc_dump_vcpu(vcpu);
@@ -455,15 +455,15 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
        switch (ws) {
        case PPC44x_TLB_PAGEID:
                tlbe->tid = get_mmucr_stid(vcpu);
-               tlbe->word0 = vcpu->arch.gpr[rs];
+               tlbe->word0 = kvmppc_get_gpr(vcpu, rs);
                break;
 
        case PPC44x_TLB_XLAT:
-               tlbe->word1 = vcpu->arch.gpr[rs];
+               tlbe->word1 = kvmppc_get_gpr(vcpu, rs);
                break;
 
        case PPC44x_TLB_ATTRIB:
-               tlbe->word2 = vcpu->arch.gpr[rs];
+               tlbe->word2 = kvmppc_get_gpr(vcpu, rs);
                break;
 
        default:
@@ -500,18 +500,20 @@ int kvmppc_44x_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb, u8 rc)
        unsigned int as = get_mmucr_sts(vcpu);
        unsigned int pid = get_mmucr_stid(vcpu);
 
-       ea = vcpu->arch.gpr[rb];
+       ea = kvmppc_get_gpr(vcpu, rb);
        if (ra)
-               ea += vcpu->arch.gpr[ra];
+               ea += kvmppc_get_gpr(vcpu, ra);
 
        gtlb_index = kvmppc_44x_tlb_index(vcpu, ea, pid, as);
        if (rc) {
+               u32 cr = kvmppc_get_cr(vcpu);
+
                if (gtlb_index < 0)
-                       vcpu->arch.cr &= ~0x20000000;
+                       kvmppc_set_cr(vcpu, cr & ~0x20000000);
                else
-                       vcpu->arch.cr |= 0x20000000;
+                       kvmppc_set_cr(vcpu, cr | 0x20000000);
        }
-       vcpu->arch.gpr[rt] = gtlb_index;
+       kvmppc_set_gpr(vcpu, rt, gtlb_index);
 
        kvmppc_set_exit_type(vcpu, EMULATED_TLBSX_EXITS);
        return EMULATE_DONE;
index fe037fd..60624cc 100644 (file)
@@ -20,6 +20,7 @@ config KVM
        bool
        select PREEMPT_NOTIFIERS
        select ANON_INODES
+       select KVM_MMIO
 
 config KVM_BOOK3S_64_HANDLER
        bool
index 3e294bd..9a271f0 100644 (file)
 
 /* #define EXIT_DEBUG */
 /* #define EXIT_DEBUG_SIMPLE */
+/* #define DEBUG_EXT */
 
-/* Without AGGRESSIVE_DEC we only fire off a DEC interrupt when DEC turns 0.
- * When set, we retrigger a DEC interrupt after that if DEC <= 0.
- * PPC32 Linux runs faster without AGGRESSIVE_DEC, PPC64 Linux requires it. */
-
-/* #define AGGRESSIVE_DEC */
+static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
 
 struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "exits",       VCPU_STAT(sum_exits) },
@@ -72,16 +69,24 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
 void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
        memcpy(get_paca()->kvm_slb, to_book3s(vcpu)->slb_shadow, sizeof(get_paca()->kvm_slb));
+       memcpy(&get_paca()->shadow_vcpu, &to_book3s(vcpu)->shadow_vcpu,
+              sizeof(get_paca()->shadow_vcpu));
        get_paca()->kvm_slb_max = to_book3s(vcpu)->slb_shadow_max;
 }
 
 void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
 {
        memcpy(to_book3s(vcpu)->slb_shadow, get_paca()->kvm_slb, sizeof(get_paca()->kvm_slb));
+       memcpy(&to_book3s(vcpu)->shadow_vcpu, &get_paca()->shadow_vcpu,
+              sizeof(get_paca()->shadow_vcpu));
        to_book3s(vcpu)->slb_shadow_max = get_paca()->kvm_slb_max;
+
+       kvmppc_giveup_ext(vcpu, MSR_FP);
+       kvmppc_giveup_ext(vcpu, MSR_VEC);
+       kvmppc_giveup_ext(vcpu, MSR_VSX);
 }
 
-#if defined(AGGRESSIVE_DEC) || defined(EXIT_DEBUG)
+#if defined(EXIT_DEBUG)
 static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
 {
        u64 jd = mftb() - vcpu->arch.dec_jiffies;
@@ -89,6 +94,23 @@ static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
 }
 #endif
 
+static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)
+{
+       vcpu->arch.shadow_msr = vcpu->arch.msr;
+       /* Guest MSR values */
+       vcpu->arch.shadow_msr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE |
+                                MSR_BE | MSR_DE;
+       /* Process MSR values */
+       vcpu->arch.shadow_msr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR |
+                                MSR_EE;
+       /* External providers the guest reserved */
+       vcpu->arch.shadow_msr |= (vcpu->arch.msr & vcpu->arch.guest_owned_ext);
+       /* 64-bit Process MSR values */
+#ifdef CONFIG_PPC_BOOK3S_64
+       vcpu->arch.shadow_msr |= MSR_ISF | MSR_HV;
+#endif
+}
+
 void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
 {
        ulong old_msr = vcpu->arch.msr;
@@ -96,12 +118,10 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
 #ifdef EXIT_DEBUG
        printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
 #endif
+
        msr &= to_book3s(vcpu)->msr_mask;
        vcpu->arch.msr = msr;
-       vcpu->arch.shadow_msr = msr | MSR_USER32;
-       vcpu->arch.shadow_msr &= ( MSR_VEC | MSR_VSX | MSR_FP | MSR_FE0 |
-                                  MSR_USER64 | MSR_SE | MSR_BE | MSR_DE |
-                                  MSR_FE1);
+       kvmppc_recalc_shadow_msr(vcpu);
 
        if (msr & (MSR_WE|MSR_POW)) {
                if (!vcpu->arch.pending_exceptions) {
@@ -125,11 +145,10 @@ void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags)
        vcpu->arch.mmu.reset_msr(vcpu);
 }
 
-void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
+static int kvmppc_book3s_vec2irqprio(unsigned int vec)
 {
        unsigned int prio;
 
-       vcpu->stat.queue_intr++;
        switch (vec) {
        case 0x100: prio = BOOK3S_IRQPRIO_SYSTEM_RESET;         break;
        case 0x200: prio = BOOK3S_IRQPRIO_MACHINE_CHECK;        break;
@@ -149,15 +168,31 @@ void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
        default:    prio = BOOK3S_IRQPRIO_MAX;                  break;
        }
 
-       set_bit(prio, &vcpu->arch.pending_exceptions);
+       return prio;
+}
+
+static void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
+                                         unsigned int vec)
+{
+       clear_bit(kvmppc_book3s_vec2irqprio(vec),
+                 &vcpu->arch.pending_exceptions);
+}
+
+void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
+{
+       vcpu->stat.queue_intr++;
+
+       set_bit(kvmppc_book3s_vec2irqprio(vec),
+               &vcpu->arch.pending_exceptions);
 #ifdef EXIT_DEBUG
        printk(KERN_INFO "Queueing interrupt %x\n", vec);
 #endif
 }
 
 
-void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
+void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags)
 {
+       to_book3s(vcpu)->prog_flags = flags;
        kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM);
 }
 
@@ -171,6 +206,11 @@ int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
        return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions);
 }
 
+void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
+{
+       kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
+}
+
 void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
                                 struct kvm_interrupt *irq)
 {
@@ -181,6 +221,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
 {
        int deliver = 1;
        int vec = 0;
+       ulong flags = 0ULL;
 
        switch (priority) {
        case BOOK3S_IRQPRIO_DECREMENTER:
@@ -214,6 +255,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
                break;
        case BOOK3S_IRQPRIO_PROGRAM:
                vec = BOOK3S_INTERRUPT_PROGRAM;
+               flags = to_book3s(vcpu)->prog_flags;
                break;
        case BOOK3S_IRQPRIO_VSX:
                vec = BOOK3S_INTERRUPT_VSX;
@@ -244,7 +286,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
 #endif
 
        if (deliver)
-               kvmppc_inject_interrupt(vcpu, vec, 0ULL);
+               kvmppc_inject_interrupt(vcpu, vec, flags);
 
        return deliver;
 }
@@ -254,21 +296,15 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
        unsigned long *pending = &vcpu->arch.pending_exceptions;
        unsigned int priority;
 
-       /* XXX be more clever here - no need to mftb() on every entry */
-       /* Issue DEC again if it's still active */
-#ifdef AGGRESSIVE_DEC
-       if (vcpu->arch.msr & MSR_EE)
-               if (kvmppc_get_dec(vcpu) & 0x80000000)
-                       kvmppc_core_queue_dec(vcpu);
-#endif
-
 #ifdef EXIT_DEBUG
        if (vcpu->arch.pending_exceptions)
                printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
 #endif
        priority = __ffs(*pending);
        while (priority <= (sizeof(unsigned int) * 8)) {
-               if (kvmppc_book3s_irqprio_deliver(vcpu, priority)) {
+               if (kvmppc_book3s_irqprio_deliver(vcpu, priority) &&
+                   (priority != BOOK3S_IRQPRIO_DECREMENTER)) {
+                       /* DEC interrupts get cleared by mtdec */
                        clear_bit(priority, &vcpu->arch.pending_exceptions);
                        break;
                }
@@ -503,14 +539,14 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
                /* Page not found in guest PTE entries */
                vcpu->arch.dear = vcpu->arch.fault_dear;
                to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr;
-               vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
+               vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL);
                kvmppc_book3s_queue_irqprio(vcpu, vec);
        } else if (page_found == -EPERM) {
                /* Storage protection */
                vcpu->arch.dear = vcpu->arch.fault_dear;
                to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr & ~DSISR_NOHPTE;
                to_book3s(vcpu)->dsisr |= DSISR_PROTFAULT;
-               vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
+               vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL);
                kvmppc_book3s_queue_irqprio(vcpu, vec);
        } else if (page_found == -EINVAL) {
                /* Page not found in guest SLB */
@@ -532,13 +568,122 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
                r = kvmppc_emulate_mmio(run, vcpu);
                if ( r == RESUME_HOST_NV )
                        r = RESUME_HOST;
-               if ( r == RESUME_GUEST_NV )
-                       r = RESUME_GUEST;
        }
 
        return r;
 }
 
+static inline int get_fpr_index(int i)
+{
+#ifdef CONFIG_VSX
+       i *= 2;
+#endif
+       return i;
+}
+
+/* Give up external provider (FPU, Altivec, VSX) */
+static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
+{
+       struct thread_struct *t = &current->thread;
+       u64 *vcpu_fpr = vcpu->arch.fpr;
+       u64 *vcpu_vsx = vcpu->arch.vsr;
+       u64 *thread_fpr = (u64*)t->fpr;
+       int i;
+
+       if (!(vcpu->arch.guest_owned_ext & msr))
+               return;
+
+#ifdef DEBUG_EXT
+       printk(KERN_INFO "Giving up ext 0x%lx\n", msr);
+#endif
+
+       switch (msr) {
+       case MSR_FP:
+               giveup_fpu(current);
+               for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
+                       vcpu_fpr[i] = thread_fpr[get_fpr_index(i)];
+
+               vcpu->arch.fpscr = t->fpscr.val;
+               break;
+       case MSR_VEC:
+#ifdef CONFIG_ALTIVEC
+               giveup_altivec(current);
+               memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr));
+               vcpu->arch.vscr = t->vscr;
+#endif
+               break;
+       case MSR_VSX:
+#ifdef CONFIG_VSX
+               __giveup_vsx(current);
+               for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr); i++)
+                       vcpu_vsx[i] = thread_fpr[get_fpr_index(i) + 1];
+#endif
+               break;
+       default:
+               BUG();
+       }
+
+       vcpu->arch.guest_owned_ext &= ~msr;
+       current->thread.regs->msr &= ~msr;
+       kvmppc_recalc_shadow_msr(vcpu);
+}
+
+/* Handle external providers (FPU, Altivec, VSX) */
+static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
+                            ulong msr)
+{
+       struct thread_struct *t = &current->thread;
+       u64 *vcpu_fpr = vcpu->arch.fpr;
+       u64 *vcpu_vsx = vcpu->arch.vsr;
+       u64 *thread_fpr = (u64*)t->fpr;
+       int i;
+
+       if (!(vcpu->arch.msr & msr)) {
+               kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+               return RESUME_GUEST;
+       }
+
+#ifdef DEBUG_EXT
+       printk(KERN_INFO "Loading up ext 0x%lx\n", msr);
+#endif
+
+       current->thread.regs->msr |= msr;
+
+       switch (msr) {
+       case MSR_FP:
+               for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
+                       thread_fpr[get_fpr_index(i)] = vcpu_fpr[i];
+
+               t->fpscr.val = vcpu->arch.fpscr;
+               t->fpexc_mode = 0;
+               kvmppc_load_up_fpu();
+               break;
+       case MSR_VEC:
+#ifdef CONFIG_ALTIVEC
+               memcpy(t->vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
+               t->vscr = vcpu->arch.vscr;
+               t->vrsave = -1;
+               kvmppc_load_up_altivec();
+#endif
+               break;
+       case MSR_VSX:
+#ifdef CONFIG_VSX
+               for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr); i++)
+                       thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i];
+               kvmppc_load_up_vsx();
+#endif
+               break;
+       default:
+               BUG();
+       }
+
+       vcpu->arch.guest_owned_ext |= msr;
+
+       kvmppc_recalc_shadow_msr(vcpu);
+
+       return RESUME_GUEST;
+}
+
 int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        unsigned int exit_nr)
 {
@@ -563,7 +708,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
        case BOOK3S_INTERRUPT_INST_STORAGE:
                vcpu->stat.pf_instruc++;
                /* only care about PTEG not found errors, but leave NX alone */
-               if (vcpu->arch.shadow_msr & 0x40000000) {
+               if (vcpu->arch.shadow_srr1 & 0x40000000) {
                        r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.pc, exit_nr);
                        vcpu->stat.sp_instruc++;
                } else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
@@ -575,7 +720,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                         */
                        kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
                } else {
-                       vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x58000000);
+                       vcpu->arch.msr |= vcpu->arch.shadow_srr1 & 0x58000000;
                        kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
                        kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
                        r = RESUME_GUEST;
@@ -621,6 +766,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
        case BOOK3S_INTERRUPT_PROGRAM:
        {
                enum emulation_result er;
+               ulong flags;
+
+               flags = vcpu->arch.shadow_srr1 & 0x1f0000ull;
 
                if (vcpu->arch.msr & MSR_PR) {
 #ifdef EXIT_DEBUG
@@ -628,7 +776,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 #endif
                        if ((vcpu->arch.last_inst & 0xff0007ff) !=
                            (INS_DCBZ & 0xfffffff7)) {
-                               kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+                               kvmppc_core_queue_program(vcpu, flags);
                                r = RESUME_GUEST;
                                break;
                        }
@@ -638,12 +786,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                er = kvmppc_emulate_instruction(run, vcpu);
                switch (er) {
                case EMULATE_DONE:
-                       r = RESUME_GUEST;
+                       r = RESUME_GUEST_NV;
                        break;
                case EMULATE_FAIL:
                        printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
                               __func__, vcpu->arch.pc, vcpu->arch.last_inst);
-                       kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+                       kvmppc_core_queue_program(vcpu, flags);
                        r = RESUME_GUEST;
                        break;
                default:
@@ -653,23 +801,30 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
        }
        case BOOK3S_INTERRUPT_SYSCALL:
 #ifdef EXIT_DEBUG
-               printk(KERN_INFO "Syscall Nr %d\n", (int)vcpu->arch.gpr[0]);
+               printk(KERN_INFO "Syscall Nr %d\n", (int)kvmppc_get_gpr(vcpu, 0));
 #endif
                vcpu->stat.syscall_exits++;
                kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
                r = RESUME_GUEST;
                break;
-       case BOOK3S_INTERRUPT_MACHINE_CHECK:
        case BOOK3S_INTERRUPT_FP_UNAVAIL:
-       case BOOK3S_INTERRUPT_TRACE:
+               r = kvmppc_handle_ext(vcpu, exit_nr, MSR_FP);
+               break;
        case BOOK3S_INTERRUPT_ALTIVEC:
+               r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VEC);
+               break;
        case BOOK3S_INTERRUPT_VSX:
+               r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VSX);
+               break;
+       case BOOK3S_INTERRUPT_MACHINE_CHECK:
+       case BOOK3S_INTERRUPT_TRACE:
                kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
                r = RESUME_GUEST;
                break;
        default:
                /* Ugh - bork here! What did we get? */
-               printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n", exit_nr, vcpu->arch.pc, vcpu->arch.shadow_msr);
+               printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n",
+                       exit_nr, vcpu->arch.pc, vcpu->arch.shadow_srr1);
                r = RESUME_HOST;
                BUG();
                break;
@@ -712,10 +867,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        int i;
 
        regs->pc = vcpu->arch.pc;
-       regs->cr = vcpu->arch.cr;
+       regs->cr = kvmppc_get_cr(vcpu);
        regs->ctr = vcpu->arch.ctr;
        regs->lr = vcpu->arch.lr;
-       regs->xer = vcpu->arch.xer;
+       regs->xer = kvmppc_get_xer(vcpu);
        regs->msr = vcpu->arch.msr;
        regs->srr0 = vcpu->arch.srr0;
        regs->srr1 = vcpu->arch.srr1;
@@ -729,7 +884,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        regs->sprg7 = vcpu->arch.sprg6;
 
        for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
-               regs->gpr[i] = vcpu->arch.gpr[i];
+               regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
 
        return 0;
 }
@@ -739,10 +894,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        int i;
 
        vcpu->arch.pc = regs->pc;
-       vcpu->arch.cr = regs->cr;
+       kvmppc_set_cr(vcpu, regs->cr);
        vcpu->arch.ctr = regs->ctr;
        vcpu->arch.lr = regs->lr;
-       vcpu->arch.xer = regs->xer;
+       kvmppc_set_xer(vcpu, regs->xer);
        kvmppc_set_msr(vcpu, regs->msr);
        vcpu->arch.srr0 = regs->srr0;
        vcpu->arch.srr1 = regs->srr1;
@@ -754,8 +909,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        vcpu->arch.sprg6 = regs->sprg5;
        vcpu->arch.sprg7 = regs->sprg6;
 
-       for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
-               vcpu->arch.gpr[i] = regs->gpr[i];
+       for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
+               kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
 
        return 0;
 }
@@ -850,7 +1005,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        int is_dirty = 0;
        int r, n;
 
-       down_write(&kvm->slots_lock);
+       mutex_lock(&kvm->slots_lock);
 
        r = kvm_get_dirty_log(kvm, log, &is_dirty);
        if (r)
@@ -858,7 +1013,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
        /* If nothing is dirty, don't bother messing with page tables. */
        if (is_dirty) {
-               memslot = &kvm->memslots[log->slot];
+               memslot = &kvm->memslots->memslots[log->slot];
 
                ga = memslot->base_gfn << PAGE_SHIFT;
                ga_end = ga + (memslot->npages << PAGE_SHIFT);
@@ -872,7 +1027,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
        r = 0;
 out:
-       up_write(&kvm->slots_lock);
+       mutex_unlock(&kvm->slots_lock);
        return r;
 }
 
@@ -910,6 +1065,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
        vcpu->arch.trampoline_lowmem = kvmppc_trampoline_lowmem;
        vcpu->arch.trampoline_enter = kvmppc_trampoline_enter;
        vcpu->arch.highmem_handler = (ulong)kvmppc_handler_highmem;
+       vcpu->arch.rmcall = *(ulong*)kvmppc_rmcall;
 
        vcpu->arch.shadow_msr = MSR_USER64;
 
@@ -943,6 +1099,10 @@ extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
 int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 {
        int ret;
+       struct thread_struct ext_bkp;
+       bool save_vec = current->thread.used_vr;
+       bool save_vsx = current->thread.used_vsr;
+       ulong ext_msr;
 
        /* No need to go into the guest when all we do is going out */
        if (signal_pending(current)) {
@@ -950,6 +1110,35 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
                return -EINTR;
        }
 
+       /* Save FPU state in stack */
+       if (current->thread.regs->msr & MSR_FP)
+               giveup_fpu(current);
+       memcpy(ext_bkp.fpr, current->thread.fpr, sizeof(current->thread.fpr));
+       ext_bkp.fpscr = current->thread.fpscr;
+       ext_bkp.fpexc_mode = current->thread.fpexc_mode;
+
+#ifdef CONFIG_ALTIVEC
+       /* Save Altivec state in stack */
+       if (save_vec) {
+               if (current->thread.regs->msr & MSR_VEC)
+                       giveup_altivec(current);
+               memcpy(ext_bkp.vr, current->thread.vr, sizeof(ext_bkp.vr));
+               ext_bkp.vscr = current->thread.vscr;
+               ext_bkp.vrsave = current->thread.vrsave;
+       }
+       ext_bkp.used_vr = current->thread.used_vr;
+#endif
+
+#ifdef CONFIG_VSX
+       /* Save VSX state in stack */
+       if (save_vsx && (current->thread.regs->msr & MSR_VSX))
+                       __giveup_vsx(current);
+       ext_bkp.used_vsr = current->thread.used_vsr;
+#endif
+
+       /* Remember the MSR with disabled extensions */
+       ext_msr = current->thread.regs->msr;
+
        /* XXX we get called with irq disabled - change that! */
        local_irq_enable();
 
@@ -957,6 +1146,32 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 
        local_irq_disable();
 
+       current->thread.regs->msr = ext_msr;
+
+       /* Make sure we save the guest FPU/Altivec/VSX state */
+       kvmppc_giveup_ext(vcpu, MSR_FP);
+       kvmppc_giveup_ext(vcpu, MSR_VEC);
+       kvmppc_giveup_ext(vcpu, MSR_VSX);
+
+       /* Restore FPU state from stack */
+       memcpy(current->thread.fpr, ext_bkp.fpr, sizeof(ext_bkp.fpr));
+       current->thread.fpscr = ext_bkp.fpscr;
+       current->thread.fpexc_mode = ext_bkp.fpexc_mode;
+
+#ifdef CONFIG_ALTIVEC
+       /* Restore Altivec state from stack */
+       if (save_vec && current->thread.used_vr) {
+               memcpy(current->thread.vr, ext_bkp.vr, sizeof(ext_bkp.vr));
+               current->thread.vscr = ext_bkp.vscr;
+               current->thread.vrsave= ext_bkp.vrsave;
+       }
+       current->thread.used_vr = ext_bkp.used_vr;
+#endif
+
+#ifdef CONFIG_VSX
+       current->thread.used_vsr = ext_bkp.used_vsr;
+#endif
+
        return ret;
 }
 
index 1027eac..2b0ee7e 100644 (file)
@@ -65,11 +65,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
        case 31:
                switch (get_xop(inst)) {
                case OP_31_XOP_MFMSR:
-                       vcpu->arch.gpr[get_rt(inst)] = vcpu->arch.msr;
+                       kvmppc_set_gpr(vcpu, get_rt(inst), vcpu->arch.msr);
                        break;
                case OP_31_XOP_MTMSRD:
                {
-                       ulong rs = vcpu->arch.gpr[get_rs(inst)];
+                       ulong rs = kvmppc_get_gpr(vcpu, get_rs(inst));
                        if (inst & 0x10000) {
                                vcpu->arch.msr &= ~(MSR_RI | MSR_EE);
                                vcpu->arch.msr |= rs & (MSR_RI | MSR_EE);
@@ -78,30 +78,30 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        break;
                }
                case OP_31_XOP_MTMSR:
-                       kvmppc_set_msr(vcpu, vcpu->arch.gpr[get_rs(inst)]);
+                       kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst)));
                        break;
                case OP_31_XOP_MFSRIN:
                {
                        int srnum;
 
-                       srnum = (vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf;
+                       srnum = (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf;
                        if (vcpu->arch.mmu.mfsrin) {
                                u32 sr;
                                sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
-                               vcpu->arch.gpr[get_rt(inst)] = sr;
+                               kvmppc_set_gpr(vcpu, get_rt(inst), sr);
                        }
                        break;
                }
                case OP_31_XOP_MTSRIN:
                        vcpu->arch.mmu.mtsrin(vcpu,
-                               (vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf,
-                               vcpu->arch.gpr[get_rs(inst)]);
+                               (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf,
+                               kvmppc_get_gpr(vcpu, get_rs(inst)));
                        break;
                case OP_31_XOP_TLBIE:
                case OP_31_XOP_TLBIEL:
                {
                        bool large = (inst & 0x00200000) ? true : false;
-                       ulong addr = vcpu->arch.gpr[get_rb(inst)];
+                       ulong addr = kvmppc_get_gpr(vcpu, get_rb(inst));
                        vcpu->arch.mmu.tlbie(vcpu, addr, large);
                        break;
                }
@@ -111,14 +111,16 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        if (!vcpu->arch.mmu.slbmte)
                                return EMULATE_FAIL;
 
-                       vcpu->arch.mmu.slbmte(vcpu, vcpu->arch.gpr[get_rs(inst)],
-                                               vcpu->arch.gpr[get_rb(inst)]);
+                       vcpu->arch.mmu.slbmte(vcpu,
+                                       kvmppc_get_gpr(vcpu, get_rs(inst)),
+                                       kvmppc_get_gpr(vcpu, get_rb(inst)));
                        break;
                case OP_31_XOP_SLBIE:
                        if (!vcpu->arch.mmu.slbie)
                                return EMULATE_FAIL;
 
-                       vcpu->arch.mmu.slbie(vcpu, vcpu->arch.gpr[get_rb(inst)]);
+                       vcpu->arch.mmu.slbie(vcpu,
+                                       kvmppc_get_gpr(vcpu, get_rb(inst)));
                        break;
                case OP_31_XOP_SLBIA:
                        if (!vcpu->arch.mmu.slbia)
@@ -132,9 +134,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        } else {
                                ulong t, rb;
 
-                               rb = vcpu->arch.gpr[get_rb(inst)];
+                               rb = kvmppc_get_gpr(vcpu, get_rb(inst));
                                t = vcpu->arch.mmu.slbmfee(vcpu, rb);
-                               vcpu->arch.gpr[get_rt(inst)] = t;
+                               kvmppc_set_gpr(vcpu, get_rt(inst), t);
                        }
                        break;
                case OP_31_XOP_SLBMFEV:
@@ -143,20 +145,20 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        } else {
                                ulong t, rb;
 
-                               rb = vcpu->arch.gpr[get_rb(inst)];
+                               rb = kvmppc_get_gpr(vcpu, get_rb(inst));
                                t = vcpu->arch.mmu.slbmfev(vcpu, rb);
-                               vcpu->arch.gpr[get_rt(inst)] = t;
+                               kvmppc_set_gpr(vcpu, get_rt(inst), t);
                        }
                        break;
                case OP_31_XOP_DCBZ:
                {
-                       ulong rb =  vcpu->arch.gpr[get_rb(inst)];
+                       ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst));
                        ulong ra = 0;
                        ulong addr;
                        u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
                        if (get_ra(inst))
-                               ra = vcpu->arch.gpr[get_ra(inst)];
+                               ra = kvmppc_get_gpr(vcpu, get_ra(inst));
 
                        addr = (ra + rb) & ~31ULL;
                        if (!(vcpu->arch.msr & MSR_SF))
@@ -233,43 +235,44 @@ static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val)
 int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 {
        int emulated = EMULATE_DONE;
+       ulong spr_val = kvmppc_get_gpr(vcpu, rs);
 
        switch (sprn) {
        case SPRN_SDR1:
-               to_book3s(vcpu)->sdr1 = vcpu->arch.gpr[rs];
+               to_book3s(vcpu)->sdr1 = spr_val;
                break;
        case SPRN_DSISR:
-               to_book3s(vcpu)->dsisr = vcpu->arch.gpr[rs];
+               to_book3s(vcpu)->dsisr = spr_val;
                break;
        case SPRN_DAR:
-               vcpu->arch.dear = vcpu->arch.gpr[rs];
+               vcpu->arch.dear = spr_val;
                break;
        case SPRN_HIOR:
-               to_book3s(vcpu)->hior = vcpu->arch.gpr[rs];
+               to_book3s(vcpu)->hior = spr_val;
                break;
        case SPRN_IBAT0U ... SPRN_IBAT3L:
        case SPRN_IBAT4U ... SPRN_IBAT7L:
        case SPRN_DBAT0U ... SPRN_DBAT3L:
        case SPRN_DBAT4U ... SPRN_DBAT7L:
-               kvmppc_write_bat(vcpu, sprn, (u32)vcpu->arch.gpr[rs]);
+               kvmppc_write_bat(vcpu, sprn, (u32)spr_val);
                /* BAT writes happen so rarely that we're ok to flush
                 * everything here */
                kvmppc_mmu_pte_flush(vcpu, 0, 0);
                break;
        case SPRN_HID0:
-               to_book3s(vcpu)->hid[0] = vcpu->arch.gpr[rs];
+               to_book3s(vcpu)->hid[0] = spr_val;
                break;
        case SPRN_HID1:
-               to_book3s(vcpu)->hid[1] = vcpu->arch.gpr[rs];
+               to_book3s(vcpu)->hid[1] = spr_val;
                break;
        case SPRN_HID2:
-               to_book3s(vcpu)->hid[2] = vcpu->arch.gpr[rs];
+               to_book3s(vcpu)->hid[2] = spr_val;
                break;
        case SPRN_HID4:
-               to_book3s(vcpu)->hid[4] = vcpu->arch.gpr[rs];
+               to_book3s(vcpu)->hid[4] = spr_val;
                break;
        case SPRN_HID5:
-               to_book3s(vcpu)->hid[5] = vcpu->arch.gpr[rs];
+               to_book3s(vcpu)->hid[5] = spr_val;
                /* guest HID5 set can change is_dcbz32 */
                if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
                    (mfmsr() & MSR_HV))
@@ -299,38 +302,38 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
 
        switch (sprn) {
        case SPRN_SDR1:
-               vcpu->arch.gpr[rt] = to_book3s(vcpu)->sdr1;
+               kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1);
                break;
        case SPRN_DSISR:
-               vcpu->arch.gpr[rt] = to_book3s(vcpu)->dsisr;
+               kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->dsisr);
                break;
        case SPRN_DAR:
-               vcpu->arch.gpr[rt] = vcpu->arch.dear;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear);
                break;
        case SPRN_HIOR:
-               vcpu->arch.gpr[rt] = to_book3s(vcpu)->hior;
+               kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hior);
                break;
        case SPRN_HID0:
-               vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[0];
+               kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[0]);
                break;
        case SPRN_HID1:
-               vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[1];
+               kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]);
                break;
        case SPRN_HID2:
-               vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[2];
+               kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]);
                break;
        case SPRN_HID4:
-               vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[4];
+               kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]);
                break;
        case SPRN_HID5:
-               vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[5];
+               kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]);
                break;
        case SPRN_THRM1:
        case SPRN_THRM2:
        case SPRN_THRM3:
        case SPRN_CTRLF:
        case SPRN_CTRLT:
-               vcpu->arch.gpr[rt] = 0;
+               kvmppc_set_gpr(vcpu, rt, 0);
                break;
        default:
                printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
index 5b2db38..1dd5a1d 100644 (file)
 
 EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter);
 EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem);
+EXPORT_SYMBOL_GPL(kvmppc_rmcall);
+EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu);
+#ifdef CONFIG_ALTIVEC
+EXPORT_SYMBOL_GPL(kvmppc_load_up_altivec);
+#endif
+#ifdef CONFIG_VSX
+EXPORT_SYMBOL_GPL(kvmppc_load_up_vsx);
+#endif
index 7b55d80..c1584d0 100644 (file)
 #define ULONG_SIZE 8
 #define VCPU_GPR(n)     (VCPU_GPRS + (n * ULONG_SIZE))
 
-.macro mfpaca tmp_reg, src_reg, offset, vcpu_reg
-       ld      \tmp_reg, (PACA_EXMC+\offset)(r13)
-       std     \tmp_reg, VCPU_GPR(\src_reg)(\vcpu_reg)
-.endm
-
 .macro DISABLE_INTERRUPTS
        mfmsr   r0
        rldicl  r0,r0,48,1
        mtmsrd  r0,1
 .endm
 
+#define VCPU_LOAD_NVGPRS(vcpu) \
+       ld      r14, VCPU_GPR(r14)(vcpu); \
+       ld      r15, VCPU_GPR(r15)(vcpu); \
+       ld      r16, VCPU_GPR(r16)(vcpu); \
+       ld      r17, VCPU_GPR(r17)(vcpu); \
+       ld      r18, VCPU_GPR(r18)(vcpu); \
+       ld      r19, VCPU_GPR(r19)(vcpu); \
+       ld      r20, VCPU_GPR(r20)(vcpu); \
+       ld      r21, VCPU_GPR(r21)(vcpu); \
+       ld      r22, VCPU_GPR(r22)(vcpu); \
+       ld      r23, VCPU_GPR(r23)(vcpu); \
+       ld      r24, VCPU_GPR(r24)(vcpu); \
+       ld      r25, VCPU_GPR(r25)(vcpu); \
+       ld      r26, VCPU_GPR(r26)(vcpu); \
+       ld      r27, VCPU_GPR(r27)(vcpu); \
+       ld      r28, VCPU_GPR(r28)(vcpu); \
+       ld      r29, VCPU_GPR(r29)(vcpu); \
+       ld      r30, VCPU_GPR(r30)(vcpu); \
+       ld      r31, VCPU_GPR(r31)(vcpu); \
+
 /*****************************************************************************
  *                                                                           *
  *     Guest entry / exit code that is in kernel module memory (highmem)     *
@@ -67,61 +82,32 @@ kvm_start_entry:
        SAVE_NVGPRS(r1)
 
        /* Save LR */
-       mflr    r14
-       std     r14, _LINK(r1)
-
-/* XXX optimize non-volatile loading away */
-kvm_start_lightweight:
+       std     r0, _LINK(r1)
 
-       DISABLE_INTERRUPTS
+       /* Load non-volatile guest state from the vcpu */
+       VCPU_LOAD_NVGPRS(r4)
 
        /* Save R1/R2 in the PACA */
-       std     r1, PACAR1(r13)
-       std     r2, (PACA_EXMC+EX_SRR0)(r13)
+       std     r1, PACA_KVM_HOST_R1(r13)
+       std     r2, PACA_KVM_HOST_R2(r13)
+
+       /* XXX swap in/out on load? */
        ld      r3, VCPU_HIGHMEM_HANDLER(r4)
-       std     r3, PACASAVEDMSR(r13)
+       std     r3, PACA_KVM_VMHANDLER(r13)
 
-       /* Load non-volatile guest state from the vcpu */
-       ld      r14, VCPU_GPR(r14)(r4)
-       ld      r15, VCPU_GPR(r15)(r4)
-       ld      r16, VCPU_GPR(r16)(r4)
-       ld      r17, VCPU_GPR(r17)(r4)
-       ld      r18, VCPU_GPR(r18)(r4)
-       ld      r19, VCPU_GPR(r19)(r4)
-       ld      r20, VCPU_GPR(r20)(r4)
-       ld      r21, VCPU_GPR(r21)(r4)
-       ld      r22, VCPU_GPR(r22)(r4)
-       ld      r23, VCPU_GPR(r23)(r4)
-       ld      r24, VCPU_GPR(r24)(r4)
-       ld      r25, VCPU_GPR(r25)(r4)
-       ld      r26, VCPU_GPR(r26)(r4)
-       ld      r27, VCPU_GPR(r27)(r4)
-       ld      r28, VCPU_GPR(r28)(r4)
-       ld      r29, VCPU_GPR(r29)(r4)
-       ld      r30, VCPU_GPR(r30)(r4)
-       ld      r31, VCPU_GPR(r31)(r4)
+kvm_start_lightweight:
 
        ld      r9, VCPU_PC(r4)                 /* r9 = vcpu->arch.pc */
        ld      r10, VCPU_SHADOW_MSR(r4)        /* r10 = vcpu->arch.shadow_msr */
 
-       ld      r3, VCPU_TRAMPOLINE_ENTER(r4)
-       mtsrr0  r3
-
-       LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR))
-       mtsrr1  r3
-
-       /* Load guest state in the respective registers */
-       lwz     r3, VCPU_CR(r4)         /* r3 = vcpu->arch.cr */
-       stw     r3, (PACA_EXMC + EX_CCR)(r13)
-
-       ld      r3, VCPU_CTR(r4)        /* r3 = vcpu->arch.ctr */
-       mtctr   r3                      /* CTR = r3 */
+       /* Load some guest state in the respective registers */
+       ld      r5, VCPU_CTR(r4)        /* r5 = vcpu->arch.ctr */
+                                       /* will be swapped in by rmcall */
 
        ld      r3, VCPU_LR(r4)         /* r3 = vcpu->arch.lr */
        mtlr    r3                      /* LR = r3 */
 
-       ld      r3, VCPU_XER(r4)        /* r3 = vcpu->arch.xer */
-       std     r3, (PACA_EXMC + EX_R3)(r13)
+       DISABLE_INTERRUPTS
 
        /* Some guests may need to have dcbz set to 32 byte length.
         *
@@ -141,36 +127,15 @@ kvm_start_lightweight:
        mtspr   SPRN_HID5,r3
 
 no_dcbz32_on:
-       /*      Load guest GPRs */
-
-       ld      r3, VCPU_GPR(r9)(r4)
-       std     r3, (PACA_EXMC + EX_R9)(r13)
-       ld      r3, VCPU_GPR(r10)(r4)
-       std     r3, (PACA_EXMC + EX_R10)(r13)
-       ld      r3, VCPU_GPR(r11)(r4)
-       std     r3, (PACA_EXMC + EX_R11)(r13)
-       ld      r3, VCPU_GPR(r12)(r4)
-       std     r3, (PACA_EXMC + EX_R12)(r13)
-       ld      r3, VCPU_GPR(r13)(r4)
-       std     r3, (PACA_EXMC + EX_R13)(r13)
-
-       ld      r0, VCPU_GPR(r0)(r4)
-       ld      r1, VCPU_GPR(r1)(r4)
-       ld      r2, VCPU_GPR(r2)(r4)
-       ld      r3, VCPU_GPR(r3)(r4)
-       ld      r5, VCPU_GPR(r5)(r4)
-       ld      r6, VCPU_GPR(r6)(r4)
-       ld      r7, VCPU_GPR(r7)(r4)
-       ld      r8, VCPU_GPR(r8)(r4)
-       ld      r4, VCPU_GPR(r4)(r4)
-
-       /* This sets the Magic value for the trampoline */
-
-       li      r11, 1
-       stb     r11, PACA_KVM_IN_GUEST(r13)
+
+       ld      r6, VCPU_RMCALL(r4)
+       mtctr   r6
+
+       ld      r3, VCPU_TRAMPOLINE_ENTER(r4)
+       LOAD_REG_IMMEDIATE(r4, MSR_KERNEL & ~(MSR_IR | MSR_DR))
 
        /* Jump to SLB patching handlder and into our guest */
-       RFI
+       bctr
 
 /*
  * This is the handler in module memory. It gets jumped at from the
@@ -184,125 +149,70 @@ kvmppc_handler_highmem:
        /*
         * Register usage at this point:
         *
-        * R00   = guest R13
-        * R01   = host R1
-        * R02   = host R2
-        * R10   = guest PC
-        * R11   = guest MSR
-        * R12   = exit handler id
-        * R13   = PACA
-        * PACA.exmc.R9    = guest R1
-        * PACA.exmc.R10   = guest R10
-        * PACA.exmc.R11   = guest R11
-        * PACA.exmc.R12   = guest R12
-        * PACA.exmc.R13   = guest R2
-        * PACA.exmc.DAR   = guest DAR
-        * PACA.exmc.DSISR = guest DSISR
-        * PACA.exmc.LR    = guest instruction
-        * PACA.exmc.CCR   = guest CR
-        * PACA.exmc.SRR0  = guest R0
+        * R0         = guest last inst
+        * R1         = host R1
+        * R2         = host R2
+        * R3         = guest PC
+        * R4         = guest MSR
+        * R5         = guest DAR
+        * R6         = guest DSISR
+        * R13        = PACA
+        * PACA.KVM.* = guest *
         *
         */
 
-       std     r3, (PACA_EXMC+EX_R3)(r13)
+       /* R7 = vcpu */
+       ld      r7, GPR4(r1)
 
-       /* save the exit id in R3 */
-       mr      r3, r12
+       /* Now save the guest state */
 
-       /* R12 = vcpu */
-       ld      r12, GPR4(r1)
+       stw     r0, VCPU_LAST_INST(r7)
 
-       /* Now save the guest state */
+       std     r3, VCPU_PC(r7)
+       std     r4, VCPU_SHADOW_SRR1(r7)
+       std     r5, VCPU_FAULT_DEAR(r7)
+       std     r6, VCPU_FAULT_DSISR(r7)
 
-       std     r0, VCPU_GPR(r13)(r12)
-       std     r4, VCPU_GPR(r4)(r12)
-       std     r5, VCPU_GPR(r5)(r12)
-       std     r6, VCPU_GPR(r6)(r12)
-       std     r7, VCPU_GPR(r7)(r12)
-       std     r8, VCPU_GPR(r8)(r12)
-       std     r9, VCPU_GPR(r9)(r12)
-
-       /* get registers from PACA */
-       mfpaca  r5, r0, EX_SRR0, r12
-       mfpaca  r5, r3, EX_R3, r12
-       mfpaca  r5, r1, EX_R9, r12
-       mfpaca  r5, r10, EX_R10, r12
-       mfpaca  r5, r11, EX_R11, r12
-       mfpaca  r5, r12, EX_R12, r12
-       mfpaca  r5, r2, EX_R13, r12
-
-       lwz     r5, (PACA_EXMC+EX_LR)(r13)
-       stw     r5, VCPU_LAST_INST(r12)
-
-       lwz     r5, (PACA_EXMC+EX_CCR)(r13)
-       stw     r5, VCPU_CR(r12)
-
-       ld      r5, VCPU_HFLAGS(r12)
+       ld      r5, VCPU_HFLAGS(r7)
        rldicl. r5, r5, 0, 63           /* CR = ((r5 & 1) == 0) */
        beq     no_dcbz32_off
 
+       li      r4, 0
        mfspr   r5,SPRN_HID5
-       rldimi  r5,r5,6,56
+       rldimi  r5,r4,6,56
        mtspr   SPRN_HID5,r5
 
 no_dcbz32_off:
 
-       /* XXX maybe skip on lightweight? */
-       std     r14, VCPU_GPR(r14)(r12)
-       std     r15, VCPU_GPR(r15)(r12)
-       std     r16, VCPU_GPR(r16)(r12)
-       std     r17, VCPU_GPR(r17)(r12)
-       std     r18, VCPU_GPR(r18)(r12)
-       std     r19, VCPU_GPR(r19)(r12)
-       std     r20, VCPU_GPR(r20)(r12)
-       std     r21, VCPU_GPR(r21)(r12)
-       std     r22, VCPU_GPR(r22)(r12)
-       std     r23, VCPU_GPR(r23)(r12)
-       std     r24, VCPU_GPR(r24)(r12)
-       std     r25, VCPU_GPR(r25)(r12)
-       std     r26, VCPU_GPR(r26)(r12)
-       std     r27, VCPU_GPR(r27)(r12)
-       std     r28, VCPU_GPR(r28)(r12)
-       std     r29, VCPU_GPR(r29)(r12)
-       std     r30, VCPU_GPR(r30)(r12)
-       std     r31, VCPU_GPR(r31)(r12)
-
-       /* Restore non-volatile host registers (r14 - r31) */
-       REST_NVGPRS(r1)
-
-       /* Save guest PC (R10) */
-       std     r10, VCPU_PC(r12)
-
-       /* Save guest msr (R11) */
-       std     r11, VCPU_SHADOW_MSR(r12)
-
-       /* Save guest CTR (in R12) */
+       std     r14, VCPU_GPR(r14)(r7)
+       std     r15, VCPU_GPR(r15)(r7)
+       std     r16, VCPU_GPR(r16)(r7)
+       std     r17, VCPU_GPR(r17)(r7)
+       std     r18, VCPU_GPR(r18)(r7)
+       std     r19, VCPU_GPR(r19)(r7)
+       std     r20, VCPU_GPR(r20)(r7)
+       std     r21, VCPU_GPR(r21)(r7)
+       std     r22, VCPU_GPR(r22)(r7)
+       std     r23, VCPU_GPR(r23)(r7)
+       std     r24, VCPU_GPR(r24)(r7)
+       std     r25, VCPU_GPR(r25)(r7)
+       std     r26, VCPU_GPR(r26)(r7)
+       std     r27, VCPU_GPR(r27)(r7)
+       std     r28, VCPU_GPR(r28)(r7)
+       std     r29, VCPU_GPR(r29)(r7)
+       std     r30, VCPU_GPR(r30)(r7)
+       std     r31, VCPU_GPR(r31)(r7)
+
+       /* Save guest CTR */
        mfctr   r5
-       std     r5, VCPU_CTR(r12)
+       std     r5, VCPU_CTR(r7)
 
        /* Save guest LR */
        mflr    r5
-       std     r5, VCPU_LR(r12)
-
-       /* Save guest XER */
-       mfxer   r5
-       std     r5, VCPU_XER(r12)
-
-       /* Save guest DAR */
-       ld      r5, (PACA_EXMC+EX_DAR)(r13)
-       std     r5, VCPU_FAULT_DEAR(r12)
-
-       /* Save guest DSISR */
-       lwz     r5, (PACA_EXMC+EX_DSISR)(r13)
-       std     r5, VCPU_FAULT_DSISR(r12)
+       std     r5, VCPU_LR(r7)
 
        /* Restore host msr -> SRR1 */
-       ld      r7, VCPU_HOST_MSR(r12)
-       mtsrr1  r7
-
-       /* Restore host IP -> SRR0 */
-       ld      r6, VCPU_HOST_RETIP(r12)
-       mtsrr0  r6
+       ld      r6, VCPU_HOST_MSR(r7)
 
        /*
         * For some interrupts, we need to call the real Linux
@@ -314,13 +224,14 @@ no_dcbz32_off:
         * r3 = address of interrupt handler (exit reason)
         */
 
-       cmpwi   r3, BOOK3S_INTERRUPT_EXTERNAL
+       cmpwi   r12, BOOK3S_INTERRUPT_EXTERNAL
        beq     call_linux_handler
-       cmpwi   r3, BOOK3S_INTERRUPT_DECREMENTER
+       cmpwi   r12, BOOK3S_INTERRUPT_DECREMENTER
        beq     call_linux_handler
 
-       /* Back to Interruptable Mode! (goto kvm_return_point) */
-       RFI
+       /* Back to EE=1 */
+       mtmsr   r6
+       b       kvm_return_point
 
 call_linux_handler:
 
@@ -333,16 +244,22 @@ call_linux_handler:
         * interrupt handler!
         *
         * R3 still contains the exit code,
-        * R6 VCPU_HOST_RETIP and
-        * R7 VCPU_HOST_MSR
+        * R5 VCPU_HOST_RETIP and
+        * R6 VCPU_HOST_MSR
         */
 
-       mtlr    r3
+       /* Restore host IP -> SRR0 */
+       ld      r5, VCPU_HOST_RETIP(r7)
+
+       /* XXX Better move to a safe function?
+        *     What if we get an HTAB flush in between mtsrr0 and mtsrr1? */
 
-       ld      r5, VCPU_TRAMPOLINE_LOWMEM(r12)
-       mtsrr0  r5
-       LOAD_REG_IMMEDIATE(r5, MSR_KERNEL & ~(MSR_IR | MSR_DR))
-       mtsrr1  r5
+       mtlr    r12
+
+       ld      r4, VCPU_TRAMPOLINE_LOWMEM(r7)
+       mtsrr0  r4
+       LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR))
+       mtsrr1  r3
 
        RFI
 
@@ -351,42 +268,51 @@ kvm_return_point:
 
        /* Jump back to lightweight entry if we're supposed to */
        /* go back into the guest */
-       mr      r5, r3
+
+       /* Pass the exit number as 3rd argument to kvmppc_handle_exit */
+       mr      r5, r12
+
        /* Restore r3 (kvm_run) and r4 (vcpu) */
        REST_2GPRS(3, r1)
        bl      KVMPPC_HANDLE_EXIT
 
-#if 0 /* XXX get lightweight exits back */
+       /* If RESUME_GUEST, get back in the loop */
        cmpwi   r3, RESUME_GUEST
-       bne     kvm_exit_heavyweight
+       beq     kvm_loop_lightweight
 
-       /* put VCPU and KVM_RUN back into place and roll again! */
-       REST_2GPRS(3, r1)
-       b       kvm_start_lightweight
+       cmpwi   r3, RESUME_GUEST_NV
+       beq     kvm_loop_heavyweight
 
-kvm_exit_heavyweight:
-       /* Restore non-volatile host registers */
-       ld      r14, _LINK(r1)
-       mtlr    r14
-       REST_NVGPRS(r1)
+kvm_exit_loop:
 
-       addi    r1, r1, SWITCH_FRAME_SIZE
-#else
        ld      r4, _LINK(r1)
        mtlr    r4
 
-       cmpwi   r3, RESUME_GUEST
-       bne     kvm_exit_heavyweight
+       /* Restore non-volatile host registers (r14 - r31) */
+       REST_NVGPRS(r1)
+
+       addi    r1, r1, SWITCH_FRAME_SIZE
+       blr
+
+kvm_loop_heavyweight:
+
+       ld      r4, _LINK(r1)
+       std     r4, (16 + SWITCH_FRAME_SIZE)(r1)
 
+       /* Load vcpu and cpu_run */
        REST_2GPRS(3, r1)
 
-       addi    r1, r1, SWITCH_FRAME_SIZE
+       /* Load non-volatile guest state from the vcpu */
+       VCPU_LOAD_NVGPRS(r4)
 
-       b       kvm_start_entry
+       /* Jump back into the beginning of this function */
+       b       kvm_start_lightweight
 
-kvm_exit_heavyweight:
+kvm_loop_lightweight:
 
-       addi    r1, r1, SWITCH_FRAME_SIZE
-#endif
+       /* We'll need the vcpu pointer */
+       REST_GPR(4, r1)
+
+       /* Jump back into the beginning of this function */
+       b       kvm_start_lightweight
 
-       blr
index e4beeb3..512dcff 100644 (file)
@@ -54,7 +54,7 @@ static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe(
                if (!vcpu_book3s->slb[i].valid)
                        continue;
 
-               if (vcpu_book3s->slb[i].large)
+               if (vcpu_book3s->slb[i].tb)
                        cmp_esid = esid_1t;
 
                if (vcpu_book3s->slb[i].esid == cmp_esid)
@@ -65,9 +65,10 @@ static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe(
                eaddr, esid, esid_1t);
        for (i = 0; i < vcpu_book3s->slb_nr; i++) {
            if (vcpu_book3s->slb[i].vsid)
-               dprintk("  %d: %c%c %llx %llx\n", i,
+               dprintk("  %d: %c%c%c %llx %llx\n", i,
                        vcpu_book3s->slb[i].valid ? 'v' : ' ',
                        vcpu_book3s->slb[i].large ? 'l' : ' ',
+                       vcpu_book3s->slb[i].tb    ? 't' : ' ',
                        vcpu_book3s->slb[i].esid,
                        vcpu_book3s->slb[i].vsid);
        }
@@ -84,7 +85,7 @@ static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
        if (!slb)
                return 0;
 
-       if (slb->large)
+       if (slb->tb)
                return (((u64)eaddr >> 12) & 0xfffffff) |
                       (((u64)slb->vsid) << 28);
 
@@ -309,7 +310,8 @@ static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb)
        slbe = &vcpu_book3s->slb[slb_nr];
 
        slbe->large = (rs & SLB_VSID_L) ? 1 : 0;
-       slbe->esid  = slbe->large ? esid_1t : esid;
+       slbe->tb    = (rs & SLB_VSID_B_1T) ? 1 : 0;
+       slbe->esid  = slbe->tb ? esid_1t : esid;
        slbe->vsid  = rs >> 12;
        slbe->valid = (rb & SLB_ESID_V) ? 1 : 0;
        slbe->Ks    = (rs & SLB_VSID_KS) ? 1 : 0;
index fb7dd2e..c83c60a 100644 (file)
@@ -45,36 +45,25 @@ kvmppc_trampoline_\intno:
         * To distinguish, we check a magic byte in the PACA
         */
        mfspr   r13, SPRN_SPRG_PACA             /* r13 = PACA */
-       std     r12, (PACA_EXMC + EX_R12)(r13)
+       std     r12, PACA_KVM_SCRATCH0(r13)
        mfcr    r12
-       stw     r12, (PACA_EXMC + EX_CCR)(r13)
+       stw     r12, PACA_KVM_SCRATCH1(r13)
        lbz     r12, PACA_KVM_IN_GUEST(r13)
-       cmpwi   r12, 0
+       cmpwi   r12, KVM_GUEST_MODE_NONE
        bne     ..kvmppc_handler_hasmagic_\intno
        /* No KVM guest? Then jump back to the Linux handler! */
-       lwz     r12, (PACA_EXMC + EX_CCR)(r13)
+       lwz     r12, PACA_KVM_SCRATCH1(r13)
        mtcr    r12
-       ld      r12, (PACA_EXMC + EX_R12)(r13)
+       ld      r12, PACA_KVM_SCRATCH0(r13)
        mfspr   r13, SPRN_SPRG_SCRATCH0         /* r13 = original r13 */
        b       kvmppc_resume_\intno            /* Get back original handler */
 
        /* Now we know we're handling a KVM guest */
 ..kvmppc_handler_hasmagic_\intno:
-       /* Unset guest state */
-       li      r12, 0
-       stb     r12, PACA_KVM_IN_GUEST(r13)
 
-       std     r1, (PACA_EXMC+EX_R9)(r13)
-       std     r10, (PACA_EXMC+EX_R10)(r13)
-       std     r11, (PACA_EXMC+EX_R11)(r13)
-       std     r2, (PACA_EXMC+EX_R13)(r13)
-
-       mfsrr0  r10
-       mfsrr1  r11
-
-       /* Restore R1/R2 so we can handle faults */
-       ld      r1, PACAR1(r13)
-       ld      r2, (PACA_EXMC+EX_SRR0)(r13)
+       /* Should we just skip the faulting instruction? */
+       cmpwi   r12, KVM_GUEST_MODE_SKIP
+       beq     kvmppc_handler_skip_ins
 
        /* Let's store which interrupt we're handling */
        li      r12, \intno
@@ -102,23 +91,107 @@ INTERRUPT_TRAMPOLINE      BOOK3S_INTERRUPT_ALTIVEC
 INTERRUPT_TRAMPOLINE   BOOK3S_INTERRUPT_VSX
 
 /*
+ * Bring us back to the faulting code, but skip the
+ * faulting instruction.
+ *
+ * This is a generic exit path from the interrupt
+ * trampolines above.
+ *
+ * Input Registers:
+ *
+ * R12               = free
+ * R13               = PACA
+ * PACA.KVM.SCRATCH0 = guest R12
+ * PACA.KVM.SCRATCH1 = guest CR
+ * SPRG_SCRATCH0     = guest R13
+ *
+ */
+kvmppc_handler_skip_ins:
+
+       /* Patch the IP to the next instruction */
+       mfsrr0  r12
+       addi    r12, r12, 4
+       mtsrr0  r12
+
+       /* Clean up all state */
+       lwz     r12, PACA_KVM_SCRATCH1(r13)
+       mtcr    r12
+       ld      r12, PACA_KVM_SCRATCH0(r13)
+       mfspr   r13, SPRN_SPRG_SCRATCH0
+
+       /* And get back into the code */
+       RFI
+
+/*
  * This trampoline brings us back to a real mode handler
  *
  * Input Registers:
  *
- * R6 = SRR0
- * R7 = SRR1
+ * R5 = SRR0
+ * R6 = SRR1
  * LR = real-mode IP
  *
  */
 .global kvmppc_handler_lowmem_trampoline
 kvmppc_handler_lowmem_trampoline:
 
-       mtsrr0  r6
-       mtsrr1  r7
+       mtsrr0  r5
+       mtsrr1  r6
        blr
 kvmppc_handler_lowmem_trampoline_end:
 
+/*
+ * Call a function in real mode
+ *
+ * Input Registers:
+ *
+ * R3 = function
+ * R4 = MSR
+ * R5 = CTR
+ *
+ */
+_GLOBAL(kvmppc_rmcall)
+       mtmsr   r4              /* Disable relocation, so mtsrr
+                                  doesn't get interrupted */
+       mtctr   r5
+       mtsrr0  r3
+       mtsrr1  r4
+       RFI
+
+/*
+ * Activate current's external feature (FPU/Altivec/VSX)
+ */
+#define define_load_up(what)                           \
+                                                       \
+_GLOBAL(kvmppc_load_up_ ## what);                      \
+       subi    r1, r1, INT_FRAME_SIZE;                 \
+       mflr    r3;                                     \
+       std     r3, _LINK(r1);                          \
+       mfmsr   r4;                                     \
+       std     r31, GPR3(r1);                          \
+       mr      r31, r4;                                \
+       li      r5, MSR_DR;                             \
+       oris    r5, r5, MSR_EE@h;                       \
+       andc    r4, r4, r5;                             \
+       mtmsr   r4;                                     \
+                                                       \
+       bl      .load_up_ ## what;                      \
+                                                       \
+       mtmsr   r31;                                    \
+       ld      r3, _LINK(r1);                          \
+       ld      r31, GPR3(r1);                          \
+       addi    r1, r1, INT_FRAME_SIZE;                 \
+       mtlr    r3;                                     \
+       blr
+
+define_load_up(fpu)
+#ifdef CONFIG_ALTIVEC
+define_load_up(altivec)
+#endif
+#ifdef CONFIG_VSX
+define_load_up(vsx)
+#endif
+
 .global kvmppc_trampoline_lowmem
 kvmppc_trampoline_lowmem:
        .long kvmppc_handler_lowmem_trampoline - _stext
index ecd237a..35b7627 100644 (file)
@@ -31,7 +31,7 @@
 #define REBOLT_SLB_ENTRY(num) \
        ld      r10, SHADOW_SLB_ESID(num)(r11); \
        cmpdi   r10, 0; \
-       beq     slb_exit_skip_1; \
+       beq     slb_exit_skip_ ## num; \
        oris    r10, r10, SLB_ESID_V@h; \
        ld      r9, SHADOW_SLB_VSID(num)(r11); \
        slbmte  r9, r10; \
@@ -51,23 +51,21 @@ kvmppc_handler_trampoline_enter:
         *
         * MSR = ~IR|DR
         * R13 = PACA
+        * R1 = host R1
+        * R2 = host R2
         * R9 = guest IP
         * R10 = guest MSR
-        * R11 = free
-        * R12 = free
-        * PACA[PACA_EXMC + EX_R9] = guest R9
-        * PACA[PACA_EXMC + EX_R10] = guest R10
-        * PACA[PACA_EXMC + EX_R11] = guest R11
-        * PACA[PACA_EXMC + EX_R12] = guest R12
-        * PACA[PACA_EXMC + EX_R13] = guest R13
-        * PACA[PACA_EXMC + EX_CCR] = guest CR
-        * PACA[PACA_EXMC + EX_R3] = guest XER
+        * all other GPRS = free
+        * PACA[KVM_CR] = guest CR
+        * PACA[KVM_XER] = guest XER
         */
 
        mtsrr0  r9
        mtsrr1  r10
 
-       mtspr   SPRN_SPRG_SCRATCH0, r0
+       /* Activate guest mode, so faults get handled by KVM */
+       li      r11, KVM_GUEST_MODE_GUEST
+       stb     r11, PACA_KVM_IN_GUEST(r13)
 
        /* Remove LPAR shadow entries */
 
@@ -131,20 +129,27 @@ slb_do_enter:
 
        /* Enter guest */
 
-       mfspr   r0, SPRN_SPRG_SCRATCH0
-
-       ld      r9, (PACA_EXMC+EX_R9)(r13)
-       ld      r10, (PACA_EXMC+EX_R10)(r13)
-       ld      r12, (PACA_EXMC+EX_R12)(r13)
-
-       lwz     r11, (PACA_EXMC+EX_CCR)(r13)
+       ld      r0, (PACA_KVM_R0)(r13)
+       ld      r1, (PACA_KVM_R1)(r13)
+       ld      r2, (PACA_KVM_R2)(r13)
+       ld      r3, (PACA_KVM_R3)(r13)
+       ld      r4, (PACA_KVM_R4)(r13)
+       ld      r5, (PACA_KVM_R5)(r13)
+       ld      r6, (PACA_KVM_R6)(r13)
+       ld      r7, (PACA_KVM_R7)(r13)
+       ld      r8, (PACA_KVM_R8)(r13)
+       ld      r9, (PACA_KVM_R9)(r13)
+       ld      r10, (PACA_KVM_R10)(r13)
+       ld      r12, (PACA_KVM_R12)(r13)
+
+       lwz     r11, (PACA_KVM_CR)(r13)
        mtcr    r11
 
-       ld      r11, (PACA_EXMC+EX_R3)(r13)
+       ld      r11, (PACA_KVM_XER)(r13)
        mtxer   r11
 
-       ld      r11, (PACA_EXMC+EX_R11)(r13)
-       ld      r13, (PACA_EXMC+EX_R13)(r13)
+       ld      r11, (PACA_KVM_R11)(r13)
+       ld      r13, (PACA_KVM_R13)(r13)
 
        RFI
 kvmppc_handler_trampoline_enter_end:
@@ -162,28 +167,54 @@ kvmppc_handler_trampoline_exit:
 
        /* Register usage at this point:
         *
-        * SPRG_SCRATCH0 = guest R13
-        * R01           = host R1
-        * R02           = host R2
-        * R10           = guest PC
-        * R11           = guest MSR
-        * R12           = exit handler id
-        * R13           = PACA
-        * PACA.exmc.CCR  = guest CR
-        * PACA.exmc.R9  = guest R1
-        * PACA.exmc.R10 = guest R10
-        * PACA.exmc.R11 = guest R11
-        * PACA.exmc.R12 = guest R12
-        * PACA.exmc.R13 = guest R2
+        * SPRG_SCRATCH0     = guest R13
+        * R12               = exit handler id
+        * R13               = PACA
+        * PACA.KVM.SCRATCH0 = guest R12
+        * PACA.KVM.SCRATCH1 = guest CR
         *
         */
 
        /* Save registers */
 
-       std     r0, (PACA_EXMC+EX_SRR0)(r13)
-       std     r9, (PACA_EXMC+EX_R3)(r13)
-       std     r10, (PACA_EXMC+EX_LR)(r13)
-       std     r11, (PACA_EXMC+EX_DAR)(r13)
+       std     r0, PACA_KVM_R0(r13)
+       std     r1, PACA_KVM_R1(r13)
+       std     r2, PACA_KVM_R2(r13)
+       std     r3, PACA_KVM_R3(r13)
+       std     r4, PACA_KVM_R4(r13)
+       std     r5, PACA_KVM_R5(r13)
+       std     r6, PACA_KVM_R6(r13)
+       std     r7, PACA_KVM_R7(r13)
+       std     r8, PACA_KVM_R8(r13)
+       std     r9, PACA_KVM_R9(r13)
+       std     r10, PACA_KVM_R10(r13)
+       std     r11, PACA_KVM_R11(r13)
+
+       /* Restore R1/R2 so we can handle faults */
+       ld      r1, PACA_KVM_HOST_R1(r13)
+       ld      r2, PACA_KVM_HOST_R2(r13)
+
+       /* Save guest PC and MSR in GPRs */
+       mfsrr0  r3
+       mfsrr1  r4
+
+       /* Get scratch'ed off registers */
+       mfspr   r9, SPRN_SPRG_SCRATCH0
+       std     r9, PACA_KVM_R13(r13)
+
+       ld      r8, PACA_KVM_SCRATCH0(r13)
+       std     r8, PACA_KVM_R12(r13)
+
+       lwz     r7, PACA_KVM_SCRATCH1(r13)
+       stw     r7, PACA_KVM_CR(r13)
+
+       /* Save more register state  */
+
+       mfxer   r6
+       stw     r6, PACA_KVM_XER(r13)
+
+       mfdar   r5
+       mfdsisr r6
 
        /*
         * In order for us to easily get the last instruction,
@@ -202,17 +233,28 @@ kvmppc_handler_trampoline_exit:
 
 ld_last_inst:
        /* Save off the guest instruction we're at */
+
+       /* Set guest mode to 'jump over instruction' so if lwz faults
+        * we'll just continue at the next IP. */
+       li      r9, KVM_GUEST_MODE_SKIP
+       stb     r9, PACA_KVM_IN_GUEST(r13)
+
        /*    1) enable paging for data */
        mfmsr   r9
        ori     r11, r9, MSR_DR                 /* Enable paging for data */
        mtmsr   r11
        /*    2) fetch the instruction */
-       lwz     r0, 0(r10)
+       li      r0, KVM_INST_FETCH_FAILED       /* In case lwz faults */
+       lwz     r0, 0(r3)
        /*    3) disable paging again */
        mtmsr   r9
 
 no_ld_last_inst:
 
+       /* Unset guest mode */
+       li      r9, KVM_GUEST_MODE_NONE
+       stb     r9, PACA_KVM_IN_GUEST(r13)
+
        /* Restore bolted entries from the shadow and fix it along the way */
 
        /* We don't store anything in entry 0, so we don't need to take care of it */
@@ -233,29 +275,27 @@ no_ld_last_inst:
 
 slb_do_exit:
 
-       /* Restore registers */
-
-       ld      r11, (PACA_EXMC+EX_DAR)(r13)
-       ld      r10, (PACA_EXMC+EX_LR)(r13)
-       ld      r9, (PACA_EXMC+EX_R3)(r13)
-
-       /* Save last inst */
-       stw     r0, (PACA_EXMC+EX_LR)(r13)
-
-       /* Save DAR and DSISR before going to paged mode */
-       mfdar   r0
-       std     r0, (PACA_EXMC+EX_DAR)(r13)
-       mfdsisr r0
-       stw     r0, (PACA_EXMC+EX_DSISR)(r13)
+       /* Register usage at this point:
+        *
+        * R0         = guest last inst
+        * R1         = host R1
+        * R2         = host R2
+        * R3         = guest PC
+        * R4         = guest MSR
+        * R5         = guest DAR
+        * R6         = guest DSISR
+        * R12        = exit handler id
+        * R13        = PACA
+        * PACA.KVM.* = guest *
+        *
+        */
 
        /* RFI into the highmem handler */
-       mfmsr   r0
-       ori     r0, r0, MSR_IR|MSR_DR|MSR_RI    /* Enable paging */
-       mtsrr1  r0
-       ld      r0, PACASAVEDMSR(r13)           /* Highmem handler address */
-       mtsrr0  r0
-
-       mfspr   r0, SPRN_SPRG_SCRATCH0
+       mfmsr   r7
+       ori     r7, r7, MSR_IR|MSR_DR|MSR_RI    /* Enable paging */
+       mtsrr1  r7
+       ld      r8, PACA_KVM_VMHANDLER(r13)     /* Highmem handler address */
+       mtsrr0  r8
 
        RFI
 kvmppc_handler_trampoline_exit_end:
index 06f5a9e..4d686cc 100644 (file)
@@ -69,10 +69,10 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu)
 
        for (i = 0; i < 32; i += 4) {
                printk("gpr%02d: %08lx %08lx %08lx %08lx\n", i,
-                      vcpu->arch.gpr[i],
-                      vcpu->arch.gpr[i+1],
-                      vcpu->arch.gpr[i+2],
-                      vcpu->arch.gpr[i+3]);
+                      kvmppc_get_gpr(vcpu, i),
+                      kvmppc_get_gpr(vcpu, i+1),
+                      kvmppc_get_gpr(vcpu, i+2),
+                      kvmppc_get_gpr(vcpu, i+3));
        }
 }
 
@@ -82,8 +82,32 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu,
        set_bit(priority, &vcpu->arch.pending_exceptions);
 }
 
-void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
+static void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu,
+                                        ulong dear_flags, ulong esr_flags)
 {
+       vcpu->arch.queued_dear = dear_flags;
+       vcpu->arch.queued_esr = esr_flags;
+       kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
+}
+
+static void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu,
+                                           ulong dear_flags, ulong esr_flags)
+{
+       vcpu->arch.queued_dear = dear_flags;
+       vcpu->arch.queued_esr = esr_flags;
+       kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
+}
+
+static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu,
+                                           ulong esr_flags)
+{
+       vcpu->arch.queued_esr = esr_flags;
+       kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
+}
+
+void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags)
+{
+       vcpu->arch.queued_esr = esr_flags;
        kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
 }
 
@@ -97,6 +121,11 @@ int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
        return test_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
 }
 
+void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
+{
+       clear_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
+}
+
 void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
                                 struct kvm_interrupt *irq)
 {
@@ -109,14 +138,19 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
 {
        int allowed = 0;
        ulong msr_mask;
+       bool update_esr = false, update_dear = false;
 
        switch (priority) {
-       case BOOKE_IRQPRIO_PROGRAM:
        case BOOKE_IRQPRIO_DTLB_MISS:
-       case BOOKE_IRQPRIO_ITLB_MISS:
-       case BOOKE_IRQPRIO_SYSCALL:
        case BOOKE_IRQPRIO_DATA_STORAGE:
+               update_dear = true;
+               /* fall through */
        case BOOKE_IRQPRIO_INST_STORAGE:
+       case BOOKE_IRQPRIO_PROGRAM:
+               update_esr = true;
+               /* fall through */
+       case BOOKE_IRQPRIO_ITLB_MISS:
+       case BOOKE_IRQPRIO_SYSCALL:
        case BOOKE_IRQPRIO_FP_UNAVAIL:
        case BOOKE_IRQPRIO_SPE_UNAVAIL:
        case BOOKE_IRQPRIO_SPE_FP_DATA:
@@ -151,6 +185,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
                vcpu->arch.srr0 = vcpu->arch.pc;
                vcpu->arch.srr1 = vcpu->arch.msr;
                vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority];
+               if (update_esr == true)
+                       vcpu->arch.esr = vcpu->arch.queued_esr;
+               if (update_dear == true)
+                       vcpu->arch.dear = vcpu->arch.queued_dear;
                kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask);
 
                clear_bit(priority, &vcpu->arch.pending_exceptions);
@@ -223,8 +261,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                if (vcpu->arch.msr & MSR_PR) {
                        /* Program traps generated by user-level software must be handled
                         * by the guest kernel. */
-                       vcpu->arch.esr = vcpu->arch.fault_esr;
-                       kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
+                       kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr);
                        r = RESUME_GUEST;
                        kvmppc_account_exit(vcpu, USR_PR_INST);
                        break;
@@ -280,16 +317,14 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                break;
 
        case BOOKE_INTERRUPT_DATA_STORAGE:
-               vcpu->arch.dear = vcpu->arch.fault_dear;
-               vcpu->arch.esr = vcpu->arch.fault_esr;
-               kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
+               kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear,
+                                              vcpu->arch.fault_esr);
                kvmppc_account_exit(vcpu, DSI_EXITS);
                r = RESUME_GUEST;
                break;
 
        case BOOKE_INTERRUPT_INST_STORAGE:
-               vcpu->arch.esr = vcpu->arch.fault_esr;
-               kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
+               kvmppc_core_queue_inst_storage(vcpu, vcpu->arch.fault_esr);
                kvmppc_account_exit(vcpu, ISI_EXITS);
                r = RESUME_GUEST;
                break;
@@ -310,9 +345,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr);
                if (gtlb_index < 0) {
                        /* The guest didn't have a mapping for it. */
-                       kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
-                       vcpu->arch.dear = vcpu->arch.fault_dear;
-                       vcpu->arch.esr = vcpu->arch.fault_esr;
+                       kvmppc_core_queue_dtlb_miss(vcpu,
+                                                   vcpu->arch.fault_dear,
+                                                   vcpu->arch.fault_esr);
                        kvmppc_mmu_dtlb_miss(vcpu);
                        kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS);
                        r = RESUME_GUEST;
@@ -426,7 +461,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
        vcpu->arch.pc = 0;
        vcpu->arch.msr = 0;
-       vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */
+       kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save LR slot */
 
        vcpu->arch.shadow_pid = 1;
 
@@ -444,10 +479,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        int i;
 
        regs->pc = vcpu->arch.pc;
-       regs->cr = vcpu->arch.cr;
+       regs->cr = kvmppc_get_cr(vcpu);
        regs->ctr = vcpu->arch.ctr;
        regs->lr = vcpu->arch.lr;
-       regs->xer = vcpu->arch.xer;
+       regs->xer = kvmppc_get_xer(vcpu);
        regs->msr = vcpu->arch.msr;
        regs->srr0 = vcpu->arch.srr0;
        regs->srr1 = vcpu->arch.srr1;
@@ -461,7 +496,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        regs->sprg7 = vcpu->arch.sprg6;
 
        for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
-               regs->gpr[i] = vcpu->arch.gpr[i];
+               regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
 
        return 0;
 }
@@ -471,10 +506,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        int i;
 
        vcpu->arch.pc = regs->pc;
-       vcpu->arch.cr = regs->cr;
+       kvmppc_set_cr(vcpu, regs->cr);
        vcpu->arch.ctr = regs->ctr;
        vcpu->arch.lr = regs->lr;
-       vcpu->arch.xer = regs->xer;
+       kvmppc_set_xer(vcpu, regs->xer);
        kvmppc_set_msr(vcpu, regs->msr);
        vcpu->arch.srr0 = regs->srr0;
        vcpu->arch.srr1 = regs->srr1;
@@ -486,8 +521,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        vcpu->arch.sprg6 = regs->sprg5;
        vcpu->arch.sprg7 = regs->sprg6;
 
-       for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
-               vcpu->arch.gpr[i] = regs->gpr[i];
+       for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
+               kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
 
        return 0;
 }
index aebc65e..cbc790e 100644 (file)
@@ -62,20 +62,20 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
 
                case OP_31_XOP_MFMSR:
                        rt = get_rt(inst);
-                       vcpu->arch.gpr[rt] = vcpu->arch.msr;
+                       kvmppc_set_gpr(vcpu, rt, vcpu->arch.msr);
                        kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
                        break;
 
                case OP_31_XOP_MTMSR:
                        rs = get_rs(inst);
                        kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
-                       kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]);
+                       kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
                        break;
 
                case OP_31_XOP_WRTEE:
                        rs = get_rs(inst);
                        vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
-                                                        | (vcpu->arch.gpr[rs] & MSR_EE);
+                                       | (kvmppc_get_gpr(vcpu, rs) & MSR_EE);
                        kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
                        break;
 
@@ -101,22 +101,23 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
 int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 {
        int emulated = EMULATE_DONE;
+       ulong spr_val = kvmppc_get_gpr(vcpu, rs);
 
        switch (sprn) {
        case SPRN_DEAR:
-               vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.dear = spr_val; break;
        case SPRN_ESR:
-               vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.esr = spr_val; break;
        case SPRN_DBCR0:
-               vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.dbcr0 = spr_val; break;
        case SPRN_DBCR1:
-               vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.dbcr1 = spr_val; break;
        case SPRN_DBSR:
-               vcpu->arch.dbsr &= ~vcpu->arch.gpr[rs]; break;
+               vcpu->arch.dbsr &= ~spr_val; break;
        case SPRN_TSR:
-               vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
+               vcpu->arch.tsr &= ~spr_val; break;
        case SPRN_TCR:
-               vcpu->arch.tcr = vcpu->arch.gpr[rs];
+               vcpu->arch.tcr = spr_val;
                kvmppc_emulate_dec(vcpu);
                break;
 
@@ -124,64 +125,64 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
         * loaded into the real SPRGs when resuming the
         * guest. */
        case SPRN_SPRG4:
-               vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.sprg4 = spr_val; break;
        case SPRN_SPRG5:
-               vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.sprg5 = spr_val; break;
        case SPRN_SPRG6:
-               vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.sprg6 = spr_val; break;
        case SPRN_SPRG7:
-               vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.sprg7 = spr_val; break;
 
        case SPRN_IVPR:
-               vcpu->arch.ivpr = vcpu->arch.gpr[rs];
+               vcpu->arch.ivpr = spr_val;
                break;
        case SPRN_IVOR0:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val;
                break;
        case SPRN_IVOR1:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = spr_val;
                break;
        case SPRN_IVOR2:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val;
                break;
        case SPRN_IVOR3:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val;
                break;
        case SPRN_IVOR4:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = spr_val;
                break;
        case SPRN_IVOR5:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = spr_val;
                break;
        case SPRN_IVOR6:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = spr_val;
                break;
        case SPRN_IVOR7:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = spr_val;
                break;
        case SPRN_IVOR8:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val;
                break;
        case SPRN_IVOR9:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val;
                break;
        case SPRN_IVOR10:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = spr_val;
                break;
        case SPRN_IVOR11:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = spr_val;
                break;
        case SPRN_IVOR12:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = spr_val;
                break;
        case SPRN_IVOR13:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = spr_val;
                break;
        case SPRN_IVOR14:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = spr_val;
                break;
        case SPRN_IVOR15:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = spr_val;
                break;
 
        default:
@@ -197,65 +198,65 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
 
        switch (sprn) {
        case SPRN_IVPR:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivpr); break;
        case SPRN_DEAR:
-               vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear); break;
        case SPRN_ESR:
-               vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.esr); break;
        case SPRN_DBCR0:
-               vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbcr0); break;
        case SPRN_DBCR1:
-               vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbcr1); break;
        case SPRN_DBSR:
-               vcpu->arch.gpr[rt] = vcpu->arch.dbsr; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbsr); break;
 
        case SPRN_IVOR0:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL]);
                break;
        case SPRN_IVOR1:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK]);
                break;
        case SPRN_IVOR2:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]);
                break;
        case SPRN_IVOR3:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE]);
                break;
        case SPRN_IVOR4:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL]);
                break;
        case SPRN_IVOR5:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT]);
                break;
        case SPRN_IVOR6:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM]);
                break;
        case SPRN_IVOR7:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL]);
                break;
        case SPRN_IVOR8:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]);
                break;
        case SPRN_IVOR9:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL]);
                break;
        case SPRN_IVOR10:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER]);
                break;
        case SPRN_IVOR11:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_FIT]);
                break;
        case SPRN_IVOR12:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG]);
                break;
        case SPRN_IVOR13:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS]);
                break;
        case SPRN_IVOR14:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS]);
                break;
        case SPRN_IVOR15:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG]);
                break;
 
        default:
index 64949ee..efa1198 100644 (file)
@@ -60,6 +60,12 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
 
        kvmppc_e500_tlb_setup(vcpu_e500);
 
+       /* Registers init */
+       vcpu->arch.pvr = mfspr(SPRN_PVR);
+
+       /* Since booke kvm only support one core, update all vcpus' PIR to 0 */
+       vcpu->vcpu_id = 0;
+
        return 0;
 }
 
index be95b8d..8e3edfb 100644 (file)
@@ -74,54 +74,59 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 {
        struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
        int emulated = EMULATE_DONE;
+       ulong spr_val = kvmppc_get_gpr(vcpu, rs);
 
        switch (sprn) {
        case SPRN_PID:
                vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
-                       vcpu->arch.pid = vcpu->arch.gpr[rs];
+                       vcpu->arch.pid = spr_val;
                break;
        case SPRN_PID1:
-               vcpu_e500->pid[1] = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->pid[1] = spr_val; break;
        case SPRN_PID2:
-               vcpu_e500->pid[2] = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->pid[2] = spr_val; break;
        case SPRN_MAS0:
-               vcpu_e500->mas0 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->mas0 = spr_val; break;
        case SPRN_MAS1:
-               vcpu_e500->mas1 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->mas1 = spr_val; break;
        case SPRN_MAS2:
-               vcpu_e500->mas2 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->mas2 = spr_val; break;
        case SPRN_MAS3:
-               vcpu_e500->mas3 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->mas3 = spr_val; break;
        case SPRN_MAS4:
-               vcpu_e500->mas4 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->mas4 = spr_val; break;
        case SPRN_MAS6:
-               vcpu_e500->mas6 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->mas6 = spr_val; break;
        case SPRN_MAS7:
-               vcpu_e500->mas7 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->mas7 = spr_val; break;
+       case SPRN_L1CSR0:
+               vcpu_e500->l1csr0 = spr_val;
+               vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC);
+               break;
        case SPRN_L1CSR1:
-               vcpu_e500->l1csr1 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->l1csr1 = spr_val; break;
        case SPRN_HID0:
-               vcpu_e500->hid0 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->hid0 = spr_val; break;
        case SPRN_HID1:
-               vcpu_e500->hid1 = vcpu->arch.gpr[rs]; break;
+               vcpu_e500->hid1 = spr_val; break;
 
        case SPRN_MMUCSR0:
                emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
-                               vcpu->arch.gpr[rs]);
+                               spr_val);
                break;
 
        /* extra exceptions */
        case SPRN_IVOR32:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val;
                break;
        case SPRN_IVOR33:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = spr_val;
                break;
        case SPRN_IVOR34:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val;
                break;
        case SPRN_IVOR35:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = vcpu->arch.gpr[rs];
+               vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val;
                break;
 
        default:
@@ -138,63 +143,57 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
 
        switch (sprn) {
        case SPRN_PID:
-               vcpu->arch.gpr[rt] = vcpu_e500->pid[0]; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[0]); break;
        case SPRN_PID1:
-               vcpu->arch.gpr[rt] = vcpu_e500->pid[1]; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[1]); break;
        case SPRN_PID2:
-               vcpu->arch.gpr[rt] = vcpu_e500->pid[2]; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[2]); break;
        case SPRN_MAS0:
-               vcpu->arch.gpr[rt] = vcpu_e500->mas0; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas0); break;
        case SPRN_MAS1:
-               vcpu->arch.gpr[rt] = vcpu_e500->mas1; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas1); break;
        case SPRN_MAS2:
-               vcpu->arch.gpr[rt] = vcpu_e500->mas2; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas2); break;
        case SPRN_MAS3:
-               vcpu->arch.gpr[rt] = vcpu_e500->mas3; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas3); break;
        case SPRN_MAS4:
-               vcpu->arch.gpr[rt] = vcpu_e500->mas4; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas4); break;
        case SPRN_MAS6:
-               vcpu->arch.gpr[rt] = vcpu_e500->mas6; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas6); break;
        case SPRN_MAS7:
-               vcpu->arch.gpr[rt] = vcpu_e500->mas7; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas7); break;
 
        case SPRN_TLB0CFG:
-               vcpu->arch.gpr[rt] = mfspr(SPRN_TLB0CFG);
-               vcpu->arch.gpr[rt] &= ~0xfffUL;
-               vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[0];
-               break;
-
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->tlb0cfg); break;
        case SPRN_TLB1CFG:
-               vcpu->arch.gpr[rt] = mfspr(SPRN_TLB1CFG);
-               vcpu->arch.gpr[rt] &= ~0xfffUL;
-               vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[1];
-               break;
-
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->tlb1cfg); break;
+       case SPRN_L1CSR0:
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr0); break;
        case SPRN_L1CSR1:
-               vcpu->arch.gpr[rt] = vcpu_e500->l1csr1; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr1); break;
        case SPRN_HID0:
-               vcpu->arch.gpr[rt] = vcpu_e500->hid0; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid0); break;
        case SPRN_HID1:
-               vcpu->arch.gpr[rt] = vcpu_e500->hid1; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid1); break;
 
        case SPRN_MMUCSR0:
-               vcpu->arch.gpr[rt] = 0; break;
+               kvmppc_set_gpr(vcpu, rt, 0); break;
 
        case SPRN_MMUCFG:
-               vcpu->arch.gpr[rt] = mfspr(SPRN_MMUCFG); break;
+               kvmppc_set_gpr(vcpu, rt, mfspr(SPRN_MMUCFG)); break;
 
        /* extra exceptions */
        case SPRN_IVOR32:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]);
                break;
        case SPRN_IVOR33:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]);
                break;
        case SPRN_IVOR34:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]);
                break;
        case SPRN_IVOR35:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]);
                break;
        default:
                emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
index fb1e1dc..0d772e6 100644 (file)
@@ -417,7 +417,7 @@ int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb)
        int esel, tlbsel;
        gva_t ea;
 
-       ea = ((ra) ? vcpu->arch.gpr[ra] : 0) + vcpu->arch.gpr[rb];
+       ea = ((ra) ? kvmppc_get_gpr(vcpu, ra) : 0) + kvmppc_get_gpr(vcpu, rb);
 
        ia = (ea >> 2) & 0x1;
 
@@ -470,7 +470,7 @@ int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb)
        struct tlbe *gtlbe = NULL;
        gva_t ea;
 
-       ea = vcpu->arch.gpr[rb];
+       ea = kvmppc_get_gpr(vcpu, rb);
 
        for (tlbsel = 0; tlbsel < 2; tlbsel++) {
                esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, as);
@@ -728,6 +728,12 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
        if (vcpu_e500->shadow_pages[1] == NULL)
                goto err_out_page0;
 
+       /* Init TLB configuration register */
+       vcpu_e500->tlb0cfg = mfspr(SPRN_TLB0CFG) & ~0xfffUL;
+       vcpu_e500->tlb0cfg |= vcpu_e500->guest_tlb_size[0];
+       vcpu_e500->tlb1cfg = mfspr(SPRN_TLB1CFG) & ~0xfffUL;
+       vcpu_e500->tlb1cfg |= vcpu_e500->guest_tlb_size[1];
+
        return 0;
 
 err_out_page0:
index 4a9ac66..cb72a65 100644 (file)
@@ -83,6 +83,9 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
 
        pr_debug("mtDEC: %x\n", vcpu->arch.dec);
 #ifdef CONFIG_PPC64
+       /* mtdec lowers the interrupt line when positive. */
+       kvmppc_core_dequeue_dec(vcpu);
+
        /* POWER4+ triggers a dec interrupt if the value is < 0 */
        if (vcpu->arch.dec & 0x80000000) {
                hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
@@ -140,14 +143,18 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
 
        pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
 
+       /* Try again next time */
+       if (inst == KVM_INST_FETCH_FAILED)
+               return EMULATE_DONE;
+
        switch (get_op(inst)) {
        case OP_TRAP:
 #ifdef CONFIG_PPC64
        case OP_TRAP_64:
+               kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
 #else
-               vcpu->arch.esr |= ESR_PTR;
+               kvmppc_core_queue_program(vcpu, vcpu->arch.esr | ESR_PTR);
 #endif
-               kvmppc_core_queue_program(vcpu);
                advance = 0;
                break;
 
@@ -167,14 +174,14 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                case OP_31_XOP_STWX:
                        rs = get_rs(inst);
                        emulated = kvmppc_handle_store(run, vcpu,
-                                                      vcpu->arch.gpr[rs],
+                                                      kvmppc_get_gpr(vcpu, rs),
                                                       4, 1);
                        break;
 
                case OP_31_XOP_STBX:
                        rs = get_rs(inst);
                        emulated = kvmppc_handle_store(run, vcpu,
-                                                      vcpu->arch.gpr[rs],
+                                                      kvmppc_get_gpr(vcpu, rs),
                                                       1, 1);
                        break;
 
@@ -183,14 +190,14 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                        ra = get_ra(inst);
                        rb = get_rb(inst);
 
-                       ea = vcpu->arch.gpr[rb];
+                       ea = kvmppc_get_gpr(vcpu, rb);
                        if (ra)
-                               ea += vcpu->arch.gpr[ra];
+                               ea += kvmppc_get_gpr(vcpu, ra);
 
                        emulated = kvmppc_handle_store(run, vcpu,
-                                                      vcpu->arch.gpr[rs],
+                                                      kvmppc_get_gpr(vcpu, rs),
                                                       1, 1);
-                       vcpu->arch.gpr[rs] = ea;
+                       kvmppc_set_gpr(vcpu, rs, ea);
                        break;
 
                case OP_31_XOP_LHZX:
@@ -203,12 +210,12 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                        ra = get_ra(inst);
                        rb = get_rb(inst);
 
-                       ea = vcpu->arch.gpr[rb];
+                       ea = kvmppc_get_gpr(vcpu, rb);
                        if (ra)
-                               ea += vcpu->arch.gpr[ra];
+                               ea += kvmppc_get_gpr(vcpu, ra);
 
                        emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
-                       vcpu->arch.gpr[ra] = ea;
+                       kvmppc_set_gpr(vcpu, ra, ea);
                        break;
 
                case OP_31_XOP_MFSPR:
@@ -217,47 +224,49 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
 
                        switch (sprn) {
                        case SPRN_SRR0:
-                               vcpu->arch.gpr[rt] = vcpu->arch.srr0; break;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr0); break;
                        case SPRN_SRR1:
-                               vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr1); break;
                        case SPRN_PVR:
-                               vcpu->arch.gpr[rt] = vcpu->arch.pvr; break;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break;
                        case SPRN_PIR:
-                               vcpu->arch.gpr[rt] = vcpu->vcpu_id; break;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break;
                        case SPRN_MSSSR0:
-                               vcpu->arch.gpr[rt] = 0; break;
+                               kvmppc_set_gpr(vcpu, rt, 0); break;
 
                        /* Note: mftb and TBRL/TBWL are user-accessible, so
                         * the guest can always access the real TB anyways.
                         * In fact, we probably will never see these traps. */
                        case SPRN_TBWL:
-                               vcpu->arch.gpr[rt] = get_tb() >> 32; break;
+                               kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break;
                        case SPRN_TBWU:
-                               vcpu->arch.gpr[rt] = get_tb(); break;
+                               kvmppc_set_gpr(vcpu, rt, get_tb()); break;
 
                        case SPRN_SPRG0:
-                               vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg0); break;
                        case SPRN_SPRG1:
-                               vcpu->arch.gpr[rt] = vcpu->arch.sprg1; break;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg1); break;
                        case SPRN_SPRG2:
-                               vcpu->arch.gpr[rt] = vcpu->arch.sprg2; break;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg2); break;
                        case SPRN_SPRG3:
-                               vcpu->arch.gpr[rt] = vcpu->arch.sprg3; break;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg3); break;
                        /* Note: SPRG4-7 are user-readable, so we don't get
                         * a trap. */
 
                        case SPRN_DEC:
                        {
                                u64 jd = get_tb() - vcpu->arch.dec_jiffies;
-                               vcpu->arch.gpr[rt] = vcpu->arch.dec - jd;
-                               pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n", vcpu->arch.dec, jd, vcpu->arch.gpr[rt]);
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd);
+                               pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n",
+                                        vcpu->arch.dec, jd,
+                                        kvmppc_get_gpr(vcpu, rt));
                                break;
                        }
                        default:
                                emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
                                if (emulated == EMULATE_FAIL) {
                                        printk("mfspr: unknown spr %x\n", sprn);
-                                       vcpu->arch.gpr[rt] = 0;
+                                       kvmppc_set_gpr(vcpu, rt, 0);
                                }
                                break;
                        }
@@ -269,7 +278,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                        rb = get_rb(inst);
 
                        emulated = kvmppc_handle_store(run, vcpu,
-                                                      vcpu->arch.gpr[rs],
+                                                      kvmppc_get_gpr(vcpu, rs),
                                                       2, 1);
                        break;
 
@@ -278,14 +287,14 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
                        ra = get_ra(inst);
                        rb = get_rb(inst);
 
-                       ea = vcpu->arch.gpr[rb];
+                       ea = kvmppc_get_gpr(vcpu, rb);
                        if (ra)
-                               ea += vcpu->arch.gpr[ra];
+                               ea += kvmppc_get_gpr(vcpu, ra);
 
                        emulated = kvmppc_handle_store(run, vcpu,
-                                                      vcpu->arch.gpr[rs],
+                                                      kvmppc_get_gpr(vcpu, rs),
                                                       2, 1);
-                       vcpu->arch.gpr[ra] = ea;
+                       kvmppc_set_gpr(vcpu, ra, ea);
                        break;
 
                case OP_31_XOP_MTSPR:
@@ -293,9 +302,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)