]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'kvm-ppc-next' of git://github.com/agraf/linux-2.6 into kvm-queue
authorPaolo Bonzini <pbonzini@redhat.com>
Wed, 29 Jan 2014 17:29:01 +0000 (18:29 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 29 Jan 2014 17:29:01 +0000 (18:29 +0100)
Conflicts:
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/booke.c

14 files changed:
1  2 
Documentation/virtual/kvm/api.txt
arch/powerpc/Kconfig
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/include/asm/kvm_book3s_asm.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/switch_to.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rm_mmu.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/book3s_rmhandlers.S
arch/powerpc/kvm/booke.c

index 366bf4b47ef48bb56a6d0dd96d6951a65c8e2129,5056baf574f4c182088c1a56457161de7dc38852..6cd63a9010fbbfd7f011a9f3085a7b688da29fba
@@@ -1838,6 -1838,7 +1838,7 @@@ registers, find a list below
    PPC   | KVM_REG_PPC_LPCR    | 64
    PPC   | KVM_REG_PPC_PPR     | 64
    PPC   | KVM_REG_PPC_ARCH_COMPAT 32
+   PPC   | KVM_REG_PPC_DABRX     | 32
    PPC   | KVM_REG_PPC_TM_GPR0 | 64
            ...
    PPC   | KVM_REG_PPC_TM_GPR31        | 64
@@@ -2104,7 -2105,7 +2105,7 @@@ Returns: 0 on success, -1 on erro
  Allows setting an eventfd to directly trigger a guest interrupt.
  kvm_irqfd.fd specifies the file descriptor to use as the eventfd and
  kvm_irqfd.gsi specifies the irqchip pin toggled by this event.  When
 -an event is tiggered on the eventfd, an interrupt is injected into
 +an event is triggered on the eventfd, an interrupt is injected into
  the guest using the specified gsi pin.  The irqfd is removed using
  the KVM_IRQFD_FLAG_DEASSIGN flag, specifying both kvm_irqfd.fd
  and kvm_irqfd.gsi.
@@@ -2115,7 -2116,7 +2116,7 @@@ interrupts.  When KVM_IRQFD_FLAG_RESAMP
  additional eventfd in the kvm_irqfd.resamplefd field.  When operating
  in resample mode, posting of an interrupt through kvm_irq.fd asserts
  the specified gsi in the irqchip.  When the irqchip is resampled, such
 -as from an EOI, the gsi is de-asserted and the user is notifed via
 +as from an EOI, the gsi is de-asserted and the user is notified via
  kvm_irqfd.resamplefd.  It is the user's responsibility to re-queue
  the interrupt if the device making use of it still requires service.
  Note that closing the resamplefd is not sufficient to disable the
@@@ -2327,7 -2328,7 +2328,7 @@@ current state.  "addr" is ignored
  Capability: basic
  Architectures: arm, arm64
  Type: vcpu ioctl
 -Parameters: struct struct kvm_vcpu_init (in)
 +Parameters: struct kvm_vcpu_init (in)
  Returns: 0 on success; -1 on error
  Errors:
    EINVAL:    the target is unknown, or the combination of features is invalid.
@@@ -2391,8 -2392,7 +2392,8 @@@ struct kvm_reg_list 
  This ioctl returns the guest registers that are supported for the
  KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
  
 -4.85 KVM_ARM_SET_DEVICE_ADDR
 +
 +4.85 KVM_ARM_SET_DEVICE_ADDR (deprecated)
  
  Capability: KVM_CAP_ARM_SET_DEVICE_ADDR
  Architectures: arm, arm64
@@@ -2430,10 -2430,6 +2431,10 @@@ must be called after calling KVM_CREATE
  KVM_RUN on any of the VCPUs.  Calling this ioctl twice for any of the
  base addresses will return -EEXIST.
  
 +Note, this IOCTL is deprecated and the more flexible SET/GET_DEVICE_ATTR API
 +should be used instead.
 +
 +
  4.86 KVM_PPC_RTAS_DEFINE_TOKEN
  
  Capability: KVM_CAP_PPC_RTAS
diff --combined arch/powerpc/Kconfig
index b2be8e8cb5c71471864e9fafebf6a475cab67bec,799d758f42c49dfd441c97cf60adcfb16426a9c3..805420853ac1eed2ed6880532c27cafaa53a26f0
@@@ -85,7 -85,6 +85,7 @@@ config GENERIC_HWEIGH
  config PPC
        bool
        default y
 +      select ARCH_MIGHT_HAVE_PC_PARPORT
        select BINFMT_ELF
        select OF
        select OF_EARLY_FLATTREE
@@@ -147,10 -146,6 +147,10 @@@ config EARLY_PRINT
        bool
        default y
  
 +config PANIC_TIMEOUT
 +      int
 +      default 180
 +
  config COMPAT
        bool
        default y if PPC64
@@@ -343,6 -338,8 +343,8 @@@ config PPC_TRANSACTIONAL_ME
         bool "Transactional Memory support for POWERPC"
         depends on PPC_BOOK3S_64
         depends on SMP
+        select ALTIVEC
+        select VSX
         default n
         ---help---
           Support user-mode Transactional Memory on POWERPC.
index bc23b1ba798068b1c5a1f21e93da8bd47018ff55,1e9c26f45d185656651d42565782399a3a604458..83851aabfdc8694c55a09e4af7686975e44d7cf2
@@@ -186,16 -186,9 +186,13 @@@ extern void kvmppc_update_lpcr(struct k
  
  extern void kvmppc_entry_trampoline(void);
  extern void kvmppc_hv_entry_trampoline(void);
- extern void kvmppc_load_up_fpu(void);
- extern void kvmppc_load_up_altivec(void);
- extern void kvmppc_load_up_vsx(void);
  extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst);
  extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst);
  extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd);
 +extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu,
 +                               struct kvm_vcpu *vcpu);
 +extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
 +                                 struct kvmppc_book3s_shadow_vcpu *svcpu);
  
  static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
  {
@@@ -271,16 -264,25 +268,25 @@@ static inline ulong kvmppc_get_pc(struc
        return vcpu->arch.pc;
  }
  
- static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu)
+ static inline bool kvmppc_need_byteswap(struct kvm_vcpu *vcpu)
  {
-       ulong pc = kvmppc_get_pc(vcpu);
+       return (vcpu->arch.shared->msr & MSR_LE) != (MSR_KERNEL & MSR_LE);
+ }
  
+ static inline u32 kvmppc_get_last_inst_internal(struct kvm_vcpu *vcpu, ulong pc)
+ {
        /* Load the instruction manually if it failed to do so in the
         * exit path */
        if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED)
                kvmppc_ld(vcpu, &pc, sizeof(u32), &vcpu->arch.last_inst, false);
  
-       return vcpu->arch.last_inst;
+       return kvmppc_need_byteswap(vcpu) ? swab32(vcpu->arch.last_inst) :
+               vcpu->arch.last_inst;
+ }
+ static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu)
+ {
+       return kvmppc_get_last_inst_internal(vcpu, kvmppc_get_pc(vcpu));
  }
  
  /*
   */
  static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu)
  {
-       ulong pc = kvmppc_get_pc(vcpu) - 4;
-       /* Load the instruction manually if it failed to do so in the
-        * exit path */
-       if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED)
-               kvmppc_ld(vcpu, &pc, sizeof(u32), &vcpu->arch.last_inst, false);
-       return vcpu->arch.last_inst;
+       return kvmppc_get_last_inst_internal(vcpu, kvmppc_get_pc(vcpu) - 4);
  }
  
  static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu)
index 192917d2239c4ed5a0eafd36b1206d176f0dddaa,490b34f5d6bf81a19346e7f6cffc82538cec55ef..f3a91dc02c981f216cc60b613347c71f988c8a7d
@@@ -79,7 -79,6 +79,7 @@@ struct kvmppc_host_state 
        ulong vmhandler;
        ulong scratch0;
        ulong scratch1;
 +      ulong scratch2;
        u8 in_guest;
        u8 restore_hid5;
        u8 napping;
@@@ -88,6 -87,7 +88,7 @@@
        u8 hwthread_req;
        u8 hwthread_state;
        u8 host_ipi;
+       u8 ptid;
        struct kvm_vcpu *kvm_vcpu;
        struct kvmppc_vcore *kvm_vcore;
        unsigned long xics_phys;
  };
  
  struct kvmppc_book3s_shadow_vcpu {
 +      bool in_use;
        ulong gpr[14];
        u32 cr;
        u32 xer;
index fa8388ed94c52e6086110bc382c7196ea32f1ad0,adf644a80a3eb0cdbdda3595978f4f3fdee4400d..6ba8d4af3999b8b700659ad5949905bf4bfe405c
  #define   CTRL_TE     0x00c00000      /* thread enable */
  #define   CTRL_RUNLATCH       0x1
  #define SPRN_DAWR     0xB4
+ #define SPRN_CIABR    0xBB
+ #define   CIABR_PRIV          0x3
+ #define   CIABR_PRIV_USER     1
+ #define   CIABR_PRIV_SUPER    2
+ #define   CIABR_PRIV_HYPER    3
  #define SPRN_DAWRX    0xBC
- #define   DAWRX_USER  (1UL << 0)
- #define   DAWRX_KERNEL        (1UL << 1)
- #define   DAWRX_HYP   (1UL << 2)
+ #define   DAWRX_USER  __MASK(0)
+ #define   DAWRX_KERNEL        __MASK(1)
+ #define   DAWRX_HYP   __MASK(2)
+ #define   DAWRX_WTI   __MASK(3)
+ #define   DAWRX_WT    __MASK(4)
+ #define   DAWRX_DR    __MASK(5)
+ #define   DAWRX_DW    __MASK(6)
  #define SPRN_DABR     0x3F5   /* Data Address Breakpoint Register */
  #define SPRN_DABR2    0x13D   /* e300 */
  #define SPRN_DABRX    0x3F7   /* Data Address Breakpoint Register Extension */
- #define   DABRX_USER  (1UL << 0)
- #define   DABRX_KERNEL        (1UL << 1)
- #define   DABRX_HYP   (1UL << 2)
- #define   DABRX_BTI   (1UL << 3)
+ #define   DABRX_USER  __MASK(0)
+ #define   DABRX_KERNEL        __MASK(1)
+ #define   DABRX_HYP   __MASK(2)
+ #define   DABRX_BTI   __MASK(3)
  #define   DABRX_ALL     (DABRX_BTI | DABRX_HYP | DABRX_KERNEL | DABRX_USER)
  #define SPRN_DAR      0x013   /* Data Address Register */
  #define SPRN_DBCR     0x136   /* e300 Data Breakpoint Control Reg */
  #define SPRN_HRMOR    0x139   /* Real mode offset register */
  #define SPRN_HSRR0    0x13A   /* Hypervisor Save/Restore 0 */
  #define SPRN_HSRR1    0x13B   /* Hypervisor Save/Restore 1 */
+ #define SPRN_IC               0x350   /* Virtual Instruction Count */
+ #define SPRN_VTB      0x351   /* Virtual Time Base */
  /* HFSCR and FSCR bit numbers are the same */
  #define FSCR_TAR_LG   8       /* Enable Target Address Register */
  #define FSCR_EBB_LG   7       /* Enable Event Based Branching */
  #define   LPCR_RMLS    0x1C000000      /* impl dependent rmo limit sel */
  #define         LPCR_RMLS_SH  (63-37)
  #define   LPCR_ILE     0x02000000      /* !HV irqs set MSR:LE */
+ #define   LPCR_AIL    0x01800000      /* Alternate interrupt location */
  #define   LPCR_AIL_0  0x00000000      /* MMU off exception offset 0x0 */
  #define   LPCR_AIL_3  0x01800000      /* MMU on exception offset 0xc00...4xxx */
- #define   LPCR_PECE   0x00007000      /* powersave exit cause enable */
+ #define   LPCR_ONL    0x00040000      /* online - PURR/SPURR count */
+ #define   LPCR_PECE   0x0001f000      /* powersave exit cause enable */
+ #define     LPCR_PECEDP       0x00010000      /* directed priv dbells cause exit */
+ #define     LPCR_PECEDH       0x00008000      /* directed hyp dbells cause exit */
  #define     LPCR_PECE0        0x00004000      /* ext. exceptions can cause exit */
  #define     LPCR_PECE1        0x00002000      /* decrementer can cause exit */
  #define     LPCR_PECE2        0x00001000      /* machine check etc can cause exit */
  #define SPRN_PCR      0x152   /* Processor compatibility register */
  #define   PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (bit NA since POWER8) */
  #define   PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (bit NA since POWER8) */
+ #define   PCR_TM_DIS  (1ul << (63-2)) /* Trans. memory disable (POWER8) */
+ #define   PCR_ARCH_206        0x4             /* Architecture 2.06 */
  #define   PCR_ARCH_205        0x2             /* Architecture 2.05 */
  #define       SPRN_HEIR       0x153   /* Hypervisor Emulated Instruction Register */
  #define SPRN_TLBINDEXR        0x154   /* P7 TLB control register */
  #define DER_EBRKE     0x00000002      /* External Breakpoint Interrupt */
  #define DER_DPIE      0x00000001      /* Dev. Port Nonmaskable Request */
  #define SPRN_DMISS    0x3D0           /* Data TLB Miss Register */
+ #define SPRN_DHDES    0x0B1           /* Directed Hyp. Doorbell Exc. State */
+ #define SPRN_DPDES    0x0B0           /* Directed Priv. Doorbell Exc. State */
  #define SPRN_EAR      0x11A           /* External Address Register */
  #define SPRN_HASH1    0x3D2           /* Primary Hash Address Register */
  #define SPRN_HASH2    0x3D3           /* Secondary Hash Address Resgister */
  #define SPRN_IABR     0x3F2   /* Instruction Address Breakpoint Register */
  #define SPRN_IABR2    0x3FA           /* 83xx */
  #define SPRN_IBCR     0x135           /* 83xx Insn Breakpoint Control Reg */
+ #define SPRN_IAMR     0x03D           /* Instr. Authority Mask Reg */
  #define SPRN_HID4     0x3F4           /* 970 HID4 */
  #define  HID4_LPES0    (1ul << (63-0)) /* LPAR env. sel. bit 0 */
  #define        HID4_RMLS2_SH   (63 - 2)       /* Real mode limit bottom 2 bits */
  #define SPRN_PIR      0x3FF   /* Processor Identification Register */
  #endif
  #define SPRN_TIR      0x1BE   /* Thread Identification Register */
+ #define SPRN_PSPB     0x09F   /* Problem State Priority Boost reg */
  #define SPRN_PTEHI    0x3D5   /* 981 7450 PTE HI word (S/W TLB load) */
  #define SPRN_PTELO    0x3D6   /* 982 7450 PTE LO word (S/W TLB load) */
  #define SPRN_PURR     0x135   /* Processor Utilization of Resources Reg */
  #define SPRN_EBBHR    804     /* Event based branch handler register */
  #define SPRN_EBBRR    805     /* Event based branch return register */
  #define SPRN_BESCR    806     /* Branch event status and control register */
+ #define SPRN_WORT     895     /* Workload optimization register - thread */
  
  #define SPRN_PMC1     787
  #define SPRN_PMC2     788
  #define   SIER_SIHV           0x1000000       /* Sampled MSR_HV */
  #define   SIER_SIAR_VALID     0x0400000       /* SIAR contents valid */
  #define   SIER_SDAR_VALID     0x0200000       /* SDAR contents valid */
+ #define SPRN_TACR     888
+ #define SPRN_TCSCR    889
+ #define SPRN_CSIGR    890
+ #define SPRN_SPMC1    892
+ #define SPRN_SPMC2    893
  
  /* When EBB is enabled, some of MMCR0/MMCR2/SIER are user accessible */
  #define MMCR0_USER_MASK       (MMCR0_FC | MMCR0_PMXE | MMCR0_PMAO)
  
  #else /* __powerpc64__ */
  
 +#if defined(CONFIG_8xx)
 +#define mftbl()               ({unsigned long rval;   \
 +                      asm volatile("mftbl %0" : "=r" (rval)); rval;})
 +#define mftbu()               ({unsigned long rval;   \
 +                      asm volatile("mftbu %0" : "=r" (rval)); rval;})
 +#else
  #define mftbl()               ({unsigned long rval;   \
                        asm volatile("mfspr %0, %1" : "=r" (rval) : \
                                "i" (SPRN_TBRL)); rval;})
  #define mftbu()               ({unsigned long rval;   \
                        asm volatile("mfspr %0, %1" : "=r" (rval) : \
                                "i" (SPRN_TBRU)); rval;})
 +#endif
  #endif /* !__powerpc64__ */
  
  #define mttbl(v)      asm volatile("mttbl %0":: "r"(v))
index aace90547614db30ea638945d30d143fbdfb336e,971ca336f451c6b4e6537354a21321d27d499efa..0e83e7d8c73f5d0845690928ce24f179f69e22b8
@@@ -25,17 -25,15 +25,15 @@@ static inline void save_tar(struct thre
  static inline void save_tar(struct thread_struct *prev) {}
  #endif
  
- extern void load_up_fpu(void);
  extern void enable_kernel_fp(void);
  extern void enable_kernel_altivec(void);
- extern void load_up_altivec(struct task_struct *);
  extern int emulate_altivec(struct pt_regs *);
  extern void __giveup_vsx(struct task_struct *);
  extern void giveup_vsx(struct task_struct *);
  extern void enable_kernel_spe(void);
  extern void giveup_spe(struct task_struct *);
  extern void load_up_spe(struct task_struct *);
 -extern void switch_booke_debug_regs(struct thread_struct *new_thread);
 +extern void switch_booke_debug_regs(struct debug_reg *new_debug);
  
  #ifndef CONFIG_SMP
  extern void discard_lazy_cpu_state(void);
index d3de01066f7dd786cd531614046b801ff7ebb18f,687f2ebf0ccee0b36675a57abeb995aef7247bd3..29eb7c19ee384f97a3933356752d37393559a60a
@@@ -425,18 -425,14 +425,14 @@@ int main(void
        DEFINE(VCPU_GUEST_PID, offsetof(struct kvm_vcpu, arch.pid));
        DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
        DEFINE(VCPU_VRSAVE, offsetof(struct kvm_vcpu, arch.vrsave));
-       DEFINE(VCPU_FPRS, offsetof(struct kvm_vcpu, arch.fpr));
-       DEFINE(VCPU_FPSCR, offsetof(struct kvm_vcpu, arch.fpscr));
+       DEFINE(VCPU_FPRS, offsetof(struct kvm_vcpu, arch.fp.fpr));
  #ifdef CONFIG_ALTIVEC
-       DEFINE(VCPU_VRS, offsetof(struct kvm_vcpu, arch.vr));
-       DEFINE(VCPU_VSCR, offsetof(struct kvm_vcpu, arch.vscr));
- #endif
- #ifdef CONFIG_VSX
-       DEFINE(VCPU_VSRS, offsetof(struct kvm_vcpu, arch.vsr));
+       DEFINE(VCPU_VRS, offsetof(struct kvm_vcpu, arch.vr.vr));
  #endif
        DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
        DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr));
        DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
+       DEFINE(VCPU_TAR, offsetof(struct kvm_vcpu, arch.tar));
        DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
        DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc));
  #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
        DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar));
        DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr));
        DEFINE(VCPU_VPA_DIRTY, offsetof(struct kvm_vcpu, arch.vpa.dirty));
+       DEFINE(VCPU_INTR_MSR, offsetof(struct kvm_vcpu, arch.intr_msr));
  #endif
  #ifdef CONFIG_PPC_BOOK3S
        DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id));
        DEFINE(VCPU_PURR, offsetof(struct kvm_vcpu, arch.purr));
        DEFINE(VCPU_SPURR, offsetof(struct kvm_vcpu, arch.spurr));
+       DEFINE(VCPU_IC, offsetof(struct kvm_vcpu, arch.ic));
+       DEFINE(VCPU_VTB, offsetof(struct kvm_vcpu, arch.vtb));
        DEFINE(VCPU_DSCR, offsetof(struct kvm_vcpu, arch.dscr));
        DEFINE(VCPU_AMR, offsetof(struct kvm_vcpu, arch.amr));
        DEFINE(VCPU_UAMOR, offsetof(struct kvm_vcpu, arch.uamor));
+       DEFINE(VCPU_IAMR, offsetof(struct kvm_vcpu, arch.iamr));
        DEFINE(VCPU_CTRL, offsetof(struct kvm_vcpu, arch.ctrl));
        DEFINE(VCPU_DABR, offsetof(struct kvm_vcpu, arch.dabr));
+       DEFINE(VCPU_DABRX, offsetof(struct kvm_vcpu, arch.dabrx));
+       DEFINE(VCPU_DAWR, offsetof(struct kvm_vcpu, arch.dawr));
+       DEFINE(VCPU_DAWRX, offsetof(struct kvm_vcpu, arch.dawrx));
+       DEFINE(VCPU_CIABR, offsetof(struct kvm_vcpu, arch.ciabr));
        DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags));
        DEFINE(VCPU_DEC, offsetof(struct kvm_vcpu, arch.dec));
        DEFINE(VCPU_DEC_EXPIRES, offsetof(struct kvm_vcpu, arch.dec_expires));
        DEFINE(VCPU_PRODDED, offsetof(struct kvm_vcpu, arch.prodded));
        DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr));
        DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc));
+       DEFINE(VCPU_SPMC, offsetof(struct kvm_vcpu, arch.spmc));
        DEFINE(VCPU_SIAR, offsetof(struct kvm_vcpu, arch.siar));
        DEFINE(VCPU_SDAR, offsetof(struct kvm_vcpu, arch.sdar));
+       DEFINE(VCPU_SIER, offsetof(struct kvm_vcpu, arch.sier));
        DEFINE(VCPU_SLB, offsetof(struct kvm_vcpu, arch.slb));
        DEFINE(VCPU_SLB_MAX, offsetof(struct kvm_vcpu, arch.slb_max));
        DEFINE(VCPU_SLB_NR, offsetof(struct kvm_vcpu, arch.slb_nr));
        DEFINE(VCPU_FAULT_DAR, offsetof(struct kvm_vcpu, arch.fault_dar));
        DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
        DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap));
-       DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid));
        DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar));
        DEFINE(VCPU_PPR, offsetof(struct kvm_vcpu, arch.ppr));
+       DEFINE(VCPU_FSCR, offsetof(struct kvm_vcpu, arch.fscr));
+       DEFINE(VCPU_PSPB, offsetof(struct kvm_vcpu, arch.pspb));
+       DEFINE(VCPU_EBBHR, offsetof(struct kvm_vcpu, arch.ebbhr));
+       DEFINE(VCPU_EBBRR, offsetof(struct kvm_vcpu, arch.ebbrr));
+       DEFINE(VCPU_BESCR, offsetof(struct kvm_vcpu, arch.bescr));
+       DEFINE(VCPU_CSIGR, offsetof(struct kvm_vcpu, arch.csigr));
+       DEFINE(VCPU_TACR, offsetof(struct kvm_vcpu, arch.tacr));
+       DEFINE(VCPU_TCSCR, offsetof(struct kvm_vcpu, arch.tcscr));
+       DEFINE(VCPU_ACOP, offsetof(struct kvm_vcpu, arch.acop));
+       DEFINE(VCPU_WORT, offsetof(struct kvm_vcpu, arch.wort));
        DEFINE(VCPU_SHADOW_SRR1, offsetof(struct kvm_vcpu, arch.shadow_srr1));
        DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count));
        DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count));
        DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
        DEFINE(VCORE_NAPPING_THREADS, offsetof(struct kvmppc_vcore, napping_threads));
+       DEFINE(VCORE_KVM, offsetof(struct kvmppc_vcore, kvm));
        DEFINE(VCORE_TB_OFFSET, offsetof(struct kvmppc_vcore, tb_offset));
        DEFINE(VCORE_LPCR, offsetof(struct kvmppc_vcore, lpcr));
        DEFINE(VCORE_PCR, offsetof(struct kvmppc_vcore, pcr));
+       DEFINE(VCORE_DPDES, offsetof(struct kvmppc_vcore, dpdes));
        DEFINE(VCPU_SLB_E, offsetof(struct kvmppc_slb, orige));
        DEFINE(VCPU_SLB_V, offsetof(struct kvmppc_slb, origv));
        DEFINE(VCPU_SLB_SIZE, sizeof(struct kvmppc_slb));
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       DEFINE(VCPU_TFHAR, offsetof(struct kvm_vcpu, arch.tfhar));
+       DEFINE(VCPU_TFIAR, offsetof(struct kvm_vcpu, arch.tfiar));
+       DEFINE(VCPU_TEXASR, offsetof(struct kvm_vcpu, arch.texasr));
+       DEFINE(VCPU_GPR_TM, offsetof(struct kvm_vcpu, arch.gpr_tm));
+       DEFINE(VCPU_FPRS_TM, offsetof(struct kvm_vcpu, arch.fp_tm.fpr));
+       DEFINE(VCPU_VRS_TM, offsetof(struct kvm_vcpu, arch.vr_tm.vr));
+       DEFINE(VCPU_VRSAVE_TM, offsetof(struct kvm_vcpu, arch.vrsave_tm));
+       DEFINE(VCPU_CR_TM, offsetof(struct kvm_vcpu, arch.cr_tm));
+       DEFINE(VCPU_LR_TM, offsetof(struct kvm_vcpu, arch.lr_tm));
+       DEFINE(VCPU_CTR_TM, offsetof(struct kvm_vcpu, arch.ctr_tm));
+       DEFINE(VCPU_AMR_TM, offsetof(struct kvm_vcpu, arch.amr_tm));
+       DEFINE(VCPU_PPR_TM, offsetof(struct kvm_vcpu, arch.ppr_tm));
+       DEFINE(VCPU_DSCR_TM, offsetof(struct kvm_vcpu, arch.dscr_tm));
+       DEFINE(VCPU_TAR_TM, offsetof(struct kvm_vcpu, arch.tar_tm));
+ #endif
  
  #ifdef CONFIG_PPC_BOOK3S_64
  #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
        HSTATE_FIELD(HSTATE_VMHANDLER, vmhandler);
        HSTATE_FIELD(HSTATE_SCRATCH0, scratch0);
        HSTATE_FIELD(HSTATE_SCRATCH1, scratch1);
 +      HSTATE_FIELD(HSTATE_SCRATCH2, scratch2);
        HSTATE_FIELD(HSTATE_IN_GUEST, in_guest);
        HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5);
        HSTATE_FIELD(HSTATE_NAPPING, napping);
        HSTATE_FIELD(HSTATE_XICS_PHYS, xics_phys);
        HSTATE_FIELD(HSTATE_SAVED_XIRR, saved_xirr);
        HSTATE_FIELD(HSTATE_HOST_IPI, host_ipi);
+       HSTATE_FIELD(HSTATE_PTID, ptid);
        HSTATE_FIELD(HSTATE_MMCR, host_mmcr);
        HSTATE_FIELD(HSTATE_PMC, host_pmc);
        HSTATE_FIELD(HSTATE_PURR, host_purr);
index c5d148434c08197034eba8ababd951176adb6a1f,22cc895333e68ea2b926efb006f1b66e45f60302..303ece75b8e4aa5b798381b4cf782a3dde8b79f6
@@@ -262,7 -262,7 +262,7 @@@ int kvmppc_mmu_hv_init(void
  
  static void kvmppc_mmu_book3s_64_hv_reset_msr(struct kvm_vcpu *vcpu)
  {
-       kvmppc_set_msr(vcpu, MSR_SF | MSR_ME);
+       kvmppc_set_msr(vcpu, vcpu->arch.intr_msr);
  }
  
  /*
@@@ -469,14 -469,11 +469,14 @@@ static int kvmppc_mmu_book3s_64_hv_xlat
                slb_v = vcpu->kvm->arch.vrma_slb_v;
        }
  
 +      preempt_disable();
        /* Find the HPTE in the hash table */
        index = kvmppc_hv_find_lock_hpte(kvm, eaddr, slb_v,
                                         HPTE_V_VALID | HPTE_V_ABSENT);
 -      if (index < 0)
 +      if (index < 0) {
 +              preempt_enable();
                return -ENOENT;
 +      }
        hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4));
        v = hptep[0] & ~HPTE_V_HVLOCK;
        gr = kvm->arch.revmap[index].guest_rpte;
        /* Unlock the HPTE */
        asm volatile("lwsync" : : : "memory");
        hptep[0] = v;
 +      preempt_enable();
  
        gpte->eaddr = eaddr;
        gpte->vpage = ((v & HPTE_V_AVPN) << 4) | ((eaddr >> 12) & 0xfff);
@@@ -562,7 -558,7 +562,7 @@@ static int kvmppc_hv_emulate_mmio(struc
         * we just return and retry the instruction.
         */
  
-       if (instruction_is_store(vcpu->arch.last_inst) != !!is_store)
+       if (instruction_is_store(kvmppc_get_last_inst(vcpu)) != !!is_store)
                return RESUME_GUEST;
  
        /*
@@@ -669,7 -665,6 +669,7 @@@ int kvmppc_book3s_hv_page_fault(struct 
                        return -EFAULT;
        } else {
                page = pages[0];
 +              pfn = page_to_pfn(page);
                if (PageHuge(page)) {
                        page = compound_head(page);
                        pte_size <<= compound_order(page);
                        }
                        rcu_read_unlock_sched();
                }
 -              pfn = page_to_pfn(page);
        }
  
        ret = -EFAULT;
                r = (r & ~(HPTE_R_W|HPTE_R_I|HPTE_R_G)) | HPTE_R_M;
        }
  
 -      /* Set the HPTE to point to pfn */
 -      r = (r & ~(HPTE_R_PP0 - pte_size)) | (pfn << PAGE_SHIFT);
 +      /*
 +       * Set the HPTE to point to pfn.
 +       * Since the pfn is at PAGE_SIZE granularity, make sure we
 +       * don't mask out lower-order bits if psize < PAGE_SIZE.
 +       */
 +      if (psize < PAGE_SIZE)
 +              psize = PAGE_SIZE;
 +      r = (r & ~(HPTE_R_PP0 - psize)) | ((pfn << PAGE_SHIFT) & ~(psize - 1));
        if (hpte_is_writable(r) && !write_ok)
                r = hpte_make_readonly(r);
        ret = RESUME_GUEST;
index 3818bd95327c5f1cf14e200d04a468bb46da6c59,f4a4c5c82fb250d7af8fac85de4cf2acaf47768c..17fc9496b6aca0d088bf6d6b13d38dca19121a13
@@@ -31,6 -31,7 +31,7 @@@
  #include <linux/spinlock.h>
  #include <linux/page-flags.h>
  #include <linux/srcu.h>
+ #include <linux/miscdevice.h>
  
  #include <asm/reg.h>
  #include <asm/cputable.h>
@@@ -85,10 -86,13 +86,13 @@@ static void kvmppc_fast_vcpu_kick_hv(st
  
        /* CPU points to the first thread of the core */
        if (cpu != me && cpu >= 0 && cpu < nr_cpu_ids) {
+ #ifdef CONFIG_KVM_XICS
                int real_cpu = cpu + vcpu->arch.ptid;
                if (paca[real_cpu].kvm_hstate.xics_phys)
                        xics_wake_cpu(real_cpu);
-               else if (cpu_online(cpu))
+               else
+ #endif
+               if (cpu_online(cpu))
                        smp_send_reschedule(cpu);
        }
        put_cpu();
  static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu)
  {
        struct kvmppc_vcore *vc = vcpu->arch.vcore;
 +      unsigned long flags;
  
 -      spin_lock(&vcpu->arch.tbacct_lock);
 +      spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags);
        if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE &&
            vc->preempt_tb != TB_NIL) {
                vc->stolen_tb += mftb() - vc->preempt_tb;
                vcpu->arch.busy_stolen += mftb() - vcpu->arch.busy_preempt;
                vcpu->arch.busy_preempt = TB_NIL;
        }
 -      spin_unlock(&vcpu->arch.tbacct_lock);
 +      spin_unlock_irqrestore(&vcpu->arch.tbacct_lock, flags);
  }
  
  static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu)
  {
        struct kvmppc_vcore *vc = vcpu->arch.vcore;
 +      unsigned long flags;
  
 -      spin_lock(&vcpu->arch.tbacct_lock);
 +      spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags);
        if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE)
                vc->preempt_tb = mftb();
        if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST)
                vcpu->arch.busy_preempt = mftb();
 -      spin_unlock(&vcpu->arch.tbacct_lock);
 +      spin_unlock_irqrestore(&vcpu->arch.tbacct_lock, flags);
  }
  
  static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
@@@ -182,14 -184,28 +186,28 @@@ int kvmppc_set_arch_compat(struct kvm_v
  
                switch (arch_compat) {
                case PVR_ARCH_205:
-                       pcr = PCR_ARCH_205;
+                       /*
+                        * If an arch bit is set in PCR, all the defined
+                        * higher-order arch bits also have to be set.
+                        */
+                       pcr = PCR_ARCH_206 | PCR_ARCH_205;
                        break;
                case PVR_ARCH_206:
                case PVR_ARCH_206p:
+                       pcr = PCR_ARCH_206;
+                       break;
+               case PVR_ARCH_207:
                        break;
                default:
                        return -EINVAL;
                }
+               if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
+                       /* POWER7 can't emulate POWER8 */
+                       if (!(pcr & PCR_ARCH_206))
+                               return -EINVAL;
+                       pcr &= ~PCR_ARCH_206;
+               }
        }
  
        spin_lock(&vc->lock);
@@@ -488,11 -504,11 +506,11 @@@ static u64 vcore_stolen_time(struct kvm
         */
        if (vc->vcore_state != VCORE_INACTIVE &&
            vc->runner->arch.run_task != current) {
 -              spin_lock(&vc->runner->arch.tbacct_lock);
 +              spin_lock_irq(&vc->runner->arch.tbacct_lock);
                p = vc->stolen_tb;
                if (vc->preempt_tb != TB_NIL)
                        p += now - vc->preempt_tb;
 -              spin_unlock(&vc->runner->arch.tbacct_lock);
 +              spin_unlock_irq(&vc->runner->arch.tbacct_lock);
        } else {
                p = vc->stolen_tb;
        }
@@@ -514,10 -530,10 +532,10 @@@ static void kvmppc_create_dtl_entry(str
        core_stolen = vcore_stolen_time(vc, now);
        stolen = core_stolen - vcpu->arch.stolen_logged;
        vcpu->arch.stolen_logged = core_stolen;
 -      spin_lock(&vcpu->arch.tbacct_lock);
 +      spin_lock_irq(&vcpu->arch.tbacct_lock);
        stolen += vcpu->arch.busy_stolen;
        vcpu->arch.busy_stolen = 0;
 -      spin_unlock(&vcpu->arch.tbacct_lock);
 +      spin_unlock_irq(&vcpu->arch.tbacct_lock);
        if (!dt || !vpa)
                return;
        memset(dt, 0, sizeof(struct dtl_entry));
@@@ -591,9 -607,7 +609,9 @@@ int kvmppc_pseries_do_hcall(struct kvm_
                if (list_empty(&vcpu->kvm->arch.rtas_tokens))
                        return RESUME_HOST;
  
 +              idx = srcu_read_lock(&vcpu->kvm->srcu);
                rc = kvmppc_rtas_hcall(vcpu);
 +              srcu_read_unlock(&vcpu->kvm->srcu, idx);
  
                if (rc == -ENOENT)
                        return RESUME_HOST;
@@@ -637,6 -651,7 +655,7 @@@ static int kvmppc_handle_exit_hv(struc
                r = RESUME_GUEST;
                break;
        case BOOK3S_INTERRUPT_EXTERNAL:
+       case BOOK3S_INTERRUPT_H_DOORBELL:
                vcpu->stat.ext_intr_exits++;
                r = RESUME_GUEST;
                break;
                /* hcall - punt to userspace */
                int i;
  
-               if (vcpu->arch.shregs.msr & MSR_PR) {
-                       /* sc 1 from userspace - reflect to guest syscall */
-                       kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_SYSCALL);
-                       r = RESUME_GUEST;
-                       break;
-               }
+               /* hypercall with MSR_PR has already been handled in rmode,
+                * and never reaches here.
+                */
                run->papr_hcall.nr = kvmppc_get_gpr(vcpu, 3);
                for (i = 0; i < 9; ++i)
                        run->papr_hcall.args[i] = kvmppc_get_gpr(vcpu, 4 + i);
         * we don't emulate any guest instructions at this stage.
         */
        case BOOK3S_INTERRUPT_H_EMUL_ASSIST:
-               kvmppc_core_queue_program(vcpu, 0x80000);
+               kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
+               r = RESUME_GUEST;
+               break;
+       /*
+        * This occurs if the guest (kernel or userspace), does something that
+        * is prohibited by HFSCR.  We just generate a program interrupt to
+        * the guest.
+        */
+       case BOOK3S_INTERRUPT_H_FAC_UNAVAIL:
+               kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
                r = RESUME_GUEST;
                break;
        default:
@@@ -765,11 -787,35 +791,35 @@@ static void kvmppc_set_lpcr(struct kvm_
        u64 mask;
  
        spin_lock(&vc->lock);
+       /*
+        * If ILE (interrupt little-endian) has changed, update the
+        * MSR_LE bit in the intr_msr for each vcpu in this vcore.
+        */
+       if ((new_lpcr & LPCR_ILE) != (vc->lpcr & LPCR_ILE)) {
+               struct kvm *kvm = vcpu->kvm;
+               struct kvm_vcpu *vcpu;
+               int i;
+               mutex_lock(&kvm->lock);
+               kvm_for_each_vcpu(i, vcpu, kvm) {
+                       if (vcpu->arch.vcore != vc)
+                               continue;
+                       if (new_lpcr & LPCR_ILE)
+                               vcpu->arch.intr_msr |= MSR_LE;
+                       else
+                               vcpu->arch.intr_msr &= ~MSR_LE;
+               }
+               mutex_unlock(&kvm->lock);
+       }
        /*
         * Userspace can only modify DPFD (default prefetch depth),
         * ILE (interrupt little-endian) and TC (translation control).
+        * On POWER8 userspace can also modify AIL (alt. interrupt loc.)
         */
        mask = LPCR_DPFD | LPCR_ILE | LPCR_TC;
+       if (cpu_has_feature(CPU_FTR_ARCH_207S))
+               mask |= LPCR_AIL;
        vc->lpcr = (vc->lpcr & ~mask) | (new_lpcr & mask);
        spin_unlock(&vc->lock);
  }
@@@ -787,6 -833,9 +837,9 @@@ static int kvmppc_get_one_reg_hv(struc
        case KVM_REG_PPC_DABR:
                *val = get_reg_val(id, vcpu->arch.dabr);
                break;
+       case KVM_REG_PPC_DABRX:
+               *val = get_reg_val(id, vcpu->arch.dabrx);
+               break;
        case KVM_REG_PPC_DSCR:
                *val = get_reg_val(id, vcpu->arch.dscr);
                break;
        case KVM_REG_PPC_UAMOR:
                *val = get_reg_val(id, vcpu->arch.uamor);
                break;
-       case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRA:
+       case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRS:
                i = id - KVM_REG_PPC_MMCR0;
                *val = get_reg_val(id, vcpu->arch.mmcr[i]);
                break;
                i = id - KVM_REG_PPC_PMC1;
                *val = get_reg_val(id, vcpu->arch.pmc[i]);
                break;
+       case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2:
+               i = id - KVM_REG_PPC_SPMC1;
+               *val = get_reg_val(id, vcpu->arch.spmc[i]);
+               break;
        case KVM_REG_PPC_SIAR:
                *val = get_reg_val(id, vcpu->arch.siar);
                break;
        case KVM_REG_PPC_SDAR:
                *val = get_reg_val(id, vcpu->arch.sdar);
                break;
- #ifdef CONFIG_VSX
-       case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
-               if (cpu_has_feature(CPU_FTR_VSX)) {
-                       /* VSX => FP reg i is stored in arch.vsr[2*i] */
-                       long int i = id - KVM_REG_PPC_FPR0;
-                       *val = get_reg_val(id, vcpu->arch.vsr[2 * i]);
-               } else {
-                       /* let generic code handle it */
-                       r = -EINVAL;
-               }
+       case KVM_REG_PPC_SIER:
+               *val = get_reg_val(id, vcpu->arch.sier);
                break;
-       case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
-               if (cpu_has_feature(CPU_FTR_VSX)) {
-                       long int i = id - KVM_REG_PPC_VSR0;
-                       val->vsxval[0] = vcpu->arch.vsr[2 * i];
-                       val->vsxval[1] = vcpu->arch.vsr[2 * i + 1];
-               } else {
-                       r = -ENXIO;
-               }
+       case KVM_REG_PPC_IAMR:
+               *val = get_reg_val(id, vcpu->arch.iamr);
+               break;
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       case KVM_REG_PPC_TFHAR:
+               *val = get_reg_val(id, vcpu->arch.tfhar);
+               break;
+       case KVM_REG_PPC_TFIAR:
+               *val = get_reg_val(id, vcpu->arch.tfiar);
+               break;
+       case KVM_REG_PPC_TEXASR:
+               *val = get_reg_val(id, vcpu->arch.texasr);
+               break;
+ #endif
+       case KVM_REG_PPC_FSCR:
+               *val = get_reg_val(id, vcpu->arch.fscr);
+               break;
+       case KVM_REG_PPC_PSPB:
+               *val = get_reg_val(id, vcpu->arch.pspb);
+               break;
+       case KVM_REG_PPC_EBBHR:
+               *val = get_reg_val(id, vcpu->arch.ebbhr);
+               break;
+       case KVM_REG_PPC_EBBRR:
+               *val = get_reg_val(id, vcpu->arch.ebbrr);
+               break;
+       case KVM_REG_PPC_BESCR:
+               *val = get_reg_val(id, vcpu->arch.bescr);
+               break;
+       case KVM_REG_PPC_TAR:
+               *val = get_reg_val(id, vcpu->arch.tar);
+               break;
+       case KVM_REG_PPC_DPDES:
+               *val = get_reg_val(id, vcpu->arch.vcore->dpdes);
+               break;
+       case KVM_REG_PPC_DAWR:
+               *val = get_reg_val(id, vcpu->arch.dawr);
+               break;
+       case KVM_REG_PPC_DAWRX:
+               *val = get_reg_val(id, vcpu->arch.dawrx);
+               break;
+       case KVM_REG_PPC_CIABR:
+               *val = get_reg_val(id, vcpu->arch.ciabr);
+               break;
+       case KVM_REG_PPC_IC:
+               *val = get_reg_val(id, vcpu->arch.ic);
+               break;
+       case KVM_REG_PPC_VTB:
+               *val = get_reg_val(id, vcpu->arch.vtb);
+               break;
+       case KVM_REG_PPC_CSIGR:
+               *val = get_reg_val(id, vcpu->arch.csigr);
+               break;
+       case KVM_REG_PPC_TACR:
+               *val = get_reg_val(id, vcpu->arch.tacr);
+               break;
+       case KVM_REG_PPC_TCSCR:
+               *val = get_reg_val(id, vcpu->arch.tcscr);
+               break;
+       case KVM_REG_PPC_PID:
+               *val = get_reg_val(id, vcpu->arch.pid);
+               break;
+       case KVM_REG_PPC_ACOP:
+               *val = get_reg_val(id, vcpu->arch.acop);
+               break;
+       case KVM_REG_PPC_WORT:
+               *val = get_reg_val(id, vcpu->arch.wort);
                break;
- #endif /* CONFIG_VSX */
        case KVM_REG_PPC_VPA_ADDR:
                spin_lock(&vcpu->arch.vpa_update_lock);
                *val = get_reg_val(id, vcpu->arch.vpa.next_gpa);
@@@ -890,6 -993,9 +997,9 @@@ static int kvmppc_set_one_reg_hv(struc
        case KVM_REG_PPC_DABR:
                vcpu->arch.dabr = set_reg_val(id, *val);
                break;
+       case KVM_REG_PPC_DABRX:
+               vcpu->arch.dabrx = set_reg_val(id, *val) & ~DABRX_HYP;
+               break;
        case KVM_REG_PPC_DSCR:
                vcpu->arch.dscr = set_reg_val(id, *val);
                break;
        case KVM_REG_PPC_UAMOR:
                vcpu->arch.uamor = set_reg_val(id, *val);
                break;
-       case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRA:
+       case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRS:
                i = id - KVM_REG_PPC_MMCR0;
                vcpu->arch.mmcr[i] = set_reg_val(id, *val);
                break;
                i = id - KVM_REG_PPC_PMC1;
                vcpu->arch.pmc[i] = set_reg_val(id, *val);
                break;
+       case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2:
+               i = id - KVM_REG_PPC_SPMC1;
+               vcpu->arch.spmc[i] = set_reg_val(id, *val);
+               break;
        case KVM_REG_PPC_SIAR:
                vcpu->arch.siar = set_reg_val(id, *val);
                break;
        case KVM_REG_PPC_SDAR:
                vcpu->arch.sdar = set_reg_val(id, *val);
                break;
- #ifdef CONFIG_VSX
-       case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
-               if (cpu_has_feature(CPU_FTR_VSX)) {
-                       /* VSX => FP reg i is stored in arch.vsr[2*i] */
-                       long int i = id - KVM_REG_PPC_FPR0;
-                       vcpu->arch.vsr[2 * i] = set_reg_val(id, *val);
-               } else {
-                       /* let generic code handle it */
-                       r = -EINVAL;
-               }
+       case KVM_REG_PPC_SIER:
+               vcpu->arch.sier = set_reg_val(id, *val);
                break;
-       case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
-               if (cpu_has_feature(CPU_FTR_VSX)) {
-                       long int i = id - KVM_REG_PPC_VSR0;
-                       vcpu->arch.vsr[2 * i] = val->vsxval[0];
-                       vcpu->arch.vsr[2 * i + 1] = val->vsxval[1];
-               } else {
-                       r = -ENXIO;
-               }
+       case KVM_REG_PPC_IAMR:
+               vcpu->arch.iamr = set_reg_val(id, *val);
+               break;
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       case KVM_REG_PPC_TFHAR:
+               vcpu->arch.tfhar = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_TFIAR:
+               vcpu->arch.tfiar = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_TEXASR:
+               vcpu->arch.texasr = set_reg_val(id, *val);
+               break;
+ #endif
+       case KVM_REG_PPC_FSCR:
+               vcpu->arch.fscr = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_PSPB:
+               vcpu->arch.pspb = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_EBBHR:
+               vcpu->arch.ebbhr = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_EBBRR:
+               vcpu->arch.ebbrr = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_BESCR:
+               vcpu->arch.bescr = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_TAR:
+               vcpu->arch.tar = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_DPDES:
+               vcpu->arch.vcore->dpdes = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_DAWR:
+               vcpu->arch.dawr = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_DAWRX:
+               vcpu->arch.dawrx = set_reg_val(id, *val) & ~DAWRX_HYP;
+               break;
+       case KVM_REG_PPC_CIABR:
+               vcpu->arch.ciabr = set_reg_val(id, *val);
+               /* Don't allow setting breakpoints in hypervisor code */
+               if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER)
+                       vcpu->arch.ciabr &= ~CIABR_PRIV;        /* disable */
+               break;
+       case KVM_REG_PPC_IC:
+               vcpu->arch.ic = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_VTB:
+               vcpu->arch.vtb = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_CSIGR:
+               vcpu->arch.csigr = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_TACR:
+               vcpu->arch.tacr = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_TCSCR:
+               vcpu->arch.tcscr = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_PID:
+               vcpu->arch.pid = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_ACOP:
+               vcpu->arch.acop = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_WORT:
+               vcpu->arch.wort = set_reg_val(id, *val);
                break;
- #endif /* CONFIG_VSX */
        case KVM_REG_PPC_VPA_ADDR:
                addr = set_reg_val(id, *val);
                r = -EINVAL;
@@@ -1017,6 -1180,7 +1184,7 @@@ static struct kvm_vcpu *kvmppc_core_vcp
        spin_lock_init(&vcpu->arch.vpa_update_lock);
        spin_lock_init(&vcpu->arch.tbacct_lock);
        vcpu->arch.busy_preempt = TB_NIL;
+       vcpu->arch.intr_msr = MSR_SF | MSR_ME;
  
        kvmppc_mmu_book3s_hv_init(vcpu);
  
                        init_waitqueue_head(&vcore->wq);
                        vcore->preempt_tb = TB_NIL;
                        vcore->lpcr = kvm->arch.lpcr;
+                       vcore->first_vcpuid = core * threads_per_core;
+                       vcore->kvm = kvm;
                }
                kvm->arch.vcores[core] = vcore;
                kvm->arch.online_vcores++;
        ++vcore->num_threads;
        spin_unlock(&vcore->lock);
        vcpu->arch.vcore = vcore;
+       vcpu->arch.ptid = vcpu->vcpu_id - vcore->first_vcpuid;
  
        vcpu->arch.cpu_type = KVM_CPU_3S_64;
        kvmppc_sanity_check(vcpu);
@@@ -1110,7 -1277,7 +1281,7 @@@ static void kvmppc_end_cede(struct kvm_
        }
  }
  
- extern int __kvmppc_vcore_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
+ extern void __kvmppc_vcore_entry(void);
  
  static void kvmppc_remove_runnable(struct kvmppc_vcore *vc,
                                   struct kvm_vcpu *vcpu)
  
        if (vcpu->arch.state != KVMPPC_VCPU_RUNNABLE)
                return;
 -      spin_lock(&vcpu->arch.tbacct_lock);
 +      spin_lock_irq(&vcpu->arch.tbacct_lock);
        now = mftb();
        vcpu->arch.busy_stolen += vcore_stolen_time(vc, now) -
                vcpu->arch.stolen_logged;
        vcpu->arch.busy_preempt = now;
        vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST;
 -      spin_unlock(&vcpu->arch.tbacct_lock);
 +      spin_unlock_irq(&vcpu->arch.tbacct_lock);
        --vc->n_runnable;
        list_del(&vcpu->arch.run_list);
  }
@@@ -1184,13 -1351,16 +1355,16 @@@ static void kvmppc_start_thread(struct 
        tpaca = &paca[cpu];
        tpaca->kvm_hstate.kvm_vcpu = vcpu;
        tpaca->kvm_hstate.kvm_vcore = vc;
-       tpaca->kvm_hstate.napping = 0;
+       tpaca->kvm_hstate.ptid = vcpu->arch.ptid;
        vcpu->cpu = vc->pcpu;
        smp_wmb();
  #if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP)
-       if (vcpu->arch.ptid) {
+       if (cpu != smp_processor_id()) {
+ #ifdef CONFIG_KVM_XICS
                xics_wake_cpu(cpu);
-               ++vc->n_woken;
+ #endif
+               if (vcpu->arch.ptid)
+                       ++vc->n_woken;
        }
  #endif
  }
@@@ -1247,10 -1417,10 +1421,10 @@@ static int on_primary_thread(void
   */
  static void kvmppc_run_core(struct kvmppc_vcore *vc)
  {
-       struct kvm_vcpu *vcpu, *vcpu0, *vnext;
+       struct kvm_vcpu *vcpu, *vnext;
        long ret;
        u64 now;
-       int ptid, i, need_vpa_update;
+       int i, need_vpa_update;
        int srcu_idx;
        struct kvm_vcpu *vcpus_to_update[threads_per_core];
  
                spin_lock(&vc->lock);
        }
  
-       /*
-        * Assign physical thread IDs, first to non-ceded vcpus
-        * and then to ceded ones.
-        */
-       ptid = 0;
-       vcpu0 = NULL;
-       list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {
-               if (!vcpu->arch.ceded) {
-                       if (!ptid)
-                               vcpu0 = vcpu;
-                       vcpu->arch.ptid = ptid++;
-               }
-       }
-       if (!vcpu0)
-               goto out;       /* nothing to run; should never happen */
-       list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list)
-               if (vcpu->arch.ceded)
-                       vcpu->arch.ptid = ptid++;
        /*
         * Make sure we are running on thread 0, and that
         * secondary threads are offline.
                kvmppc_create_dtl_entry(vcpu, vc);
        }
  
+       /* Set this explicitly in case thread 0 doesn't have a vcpu */
+       get_paca()->kvm_hstate.kvm_vcore = vc;
+       get_paca()->kvm_hstate.ptid = 0;
        vc->vcore_state = VCORE_RUNNING;
        preempt_disable();
        spin_unlock(&vc->lock);
  
        kvm_guest_enter();
  
-       srcu_idx = srcu_read_lock(&vcpu0->kvm->srcu);
+       srcu_idx = srcu_read_lock(&vc->kvm->srcu);
  
-       __kvmppc_vcore_entry(NULL, vcpu0);
+       __kvmppc_vcore_entry();
  
        spin_lock(&vc->lock);
        /* disable sending of IPIs on virtual external irqs */
        vc->vcore_state = VCORE_EXITING;
        spin_unlock(&vc->lock);
  
-       srcu_read_unlock(&vcpu0->kvm->srcu, srcu_idx);
+       srcu_read_unlock(&vc->kvm->srcu, srcu_idx);
  
        /* make sure updates to secondary vcpu structs are visible now */
        smp_mb();
        kvm_guest_exit();
  
        preempt_enable();
 -      kvm_resched(vcpu);
 +      cond_resched();
  
        spin_lock(&vc->lock);
        now = get_tb();
@@@ -1453,7 -1608,6 +1612,6 @@@ static int kvmppc_run_vcpu(struct kvm_r
        if (!signal_pending(current)) {
                if (vc->vcore_state == VCORE_RUNNING &&
                    VCORE_EXIT_COUNT(vc) == 0) {
-                       vcpu->arch.ptid = vc->n_runnable - 1;
                        kvmppc_create_dtl_entry(vcpu, vc);
                        kvmppc_start_thread(vcpu);
                } else if (vc->vcore_state == VCORE_SLEEPING) {
@@@ -2048,6 -2202,9 +2206,9 @@@ static int kvmppc_core_init_vm_hv(struc
                        LPCR_VPM0 | LPCR_VPM1;
                kvm->arch.vrma_slb_v = SLB_VSID_B_1T |
                        (VRMA_VSID << SLB_VSID_SHIFT_1T);
+               /* On POWER8 turn on online bit to enable PURR/SPURR */
+               if (cpu_has_feature(CPU_FTR_ARCH_207S))
+                       lpcr |= LPCR_ONL;
        }
        kvm->arch.lpcr = lpcr;
  
@@@ -2222,3 -2379,5 +2383,5 @@@ static void kvmppc_book3s_exit_hv(void
  module_init(kvmppc_book3s_init_hv);
  module_exit(kvmppc_book3s_exit_hv);
  MODULE_LICENSE("GPL");
+ MODULE_ALIAS_MISCDEV(KVM_MINOR);
+ MODULE_ALIAS("devname:kvm");
index 8689e2e308573b0df26996e2ebfed77e235df59c,daa19a043677db89228abea7ca37f01d2709815f..37fb3caa4c80a59c5162b92943e1d7878991b8f1
@@@ -134,7 -134,7 +134,7 @@@ static void remove_revmap_chain(struct 
        unlock_rmap(rmap);
  }
  
- static pte_t lookup_linux_pte(pgd_t *pgdir, unsigned long hva,
+ static pte_t lookup_linux_pte_and_update(pgd_t *pgdir, unsigned long hva,
                              int writing, unsigned long *pte_sizep)
  {
        pte_t *ptep;
@@@ -225,27 -225,27 +225,28 @@@ long kvmppc_do_h_enter(struct kvm *kvm
                is_io = pa & (HPTE_R_I | HPTE_R_W);
                pte_size = PAGE_SIZE << (pa & KVMPPC_PAGE_ORDER_MASK);
                pa &= PAGE_MASK;
 +              pa |= gpa & ~PAGE_MASK;
        } else {
                /* Translate to host virtual address */
                hva = __gfn_to_hva_memslot(memslot, gfn);
  
                /* Look up the Linux PTE for the backing page */
                pte_size = psize;
-               pte = lookup_linux_pte(pgdir, hva, writing, &pte_size);
+               pte = lookup_linux_pte_and_update(pgdir, hva, writing,
+                                                 &pte_size);
                if (pte_present(pte)) {
                        if (writing && !pte_write(pte))
                                /* make the actual HPTE be read-only */
                                ptel = hpte_make_readonly(ptel);
                        is_io = hpte_cache_bits(pte_val(pte));
                        pa = pte_pfn(pte) << PAGE_SHIFT;
 +                      pa |= hva & (pte_size - 1);
 +                      pa |= gpa & ~PAGE_MASK;
                }
        }
  
        if (pte_size < psize)
                return H_PARAMETER;
 -      if (pa && pte_size > psize)
 -              pa |= gpa & (pte_size - 1);
  
        ptel &= ~(HPTE_R_PP0 - psize);
        ptel |= pa;
@@@ -672,7 -672,8 +673,8 @@@ long kvmppc_h_protect(struct kvm_vcpu *
                        memslot = __gfn_to_memslot(kvm_memslots(kvm), gfn);
                        if (memslot) {
                                hva = __gfn_to_hva_memslot(memslot, gfn);
-                               pte = lookup_linux_pte(pgdir, hva, 1, &psize);
+                               pte = lookup_linux_pte_and_update(pgdir, hva,
+                                                                 1, &psize);
                                if (pte_present(pte) && !pte_write(pte))
                                        r = hpte_make_readonly(r);
                        }
@@@ -750,10 -751,6 +752,10 @@@ static int slb_base_page_shift[4] = 
        20,     /* 1M, unsupported */
  };
  
 +/* When called from virtmode, this func should be protected by
 + * preempt_disable(), otherwise, the holding of HPTE_V_HVLOCK
 + * can trigger deadlock issue.
 + */
  long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
                              unsigned long valid)
  {
index be4fa04a37c96d56d5f07d241395afe22e1627dd,dfa144cb199bb408d7df7b10d481383f924b3a44..e66d4ec04d953a78a314b43a3a07f47ca27f5ae7
  #error Need to fix lppaca and SLB shadow accesses in little endian mode
  #endif
  
+ /* Values in HSTATE_NAPPING(r13) */
+ #define NAPPING_CEDE  1
+ #define NAPPING_NOVCPU        2
  /*
   * Call kvmppc_hv_entry in real mode.
   * Must be called with interrupts hard-disabled.
@@@ -57,29 -61,23 +61,23 @@@ _GLOBAL(kvmppc_hv_entry_trampoline
        RFI
  
  kvmppc_call_hv_entry:
+       ld      r4, HSTATE_KVM_VCPU(r13)
        bl      kvmppc_hv_entry
  
        /* Back from guest - restore host state and return to caller */
  
+ BEGIN_FTR_SECTION
        /* Restore host DABR and DABRX */
        ld      r5,HSTATE_DABR(r13)
        li      r6,7
        mtspr   SPRN_DABR,r5
        mtspr   SPRN_DABRX,r6
+ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
  
        /* Restore SPRG3 */
        ld      r3,PACA_SPRG3(r13)
        mtspr   SPRN_SPRG3,r3
  
-       /*
-        * Reload DEC.  HDEC interrupts were disabled when
-        * we reloaded the host's LPCR value.
-        */
-       ld      r3, HSTATE_DECEXP(r13)
-       mftb    r4
-       subf    r4, r4, r3
-       mtspr   SPRN_DEC, r4
        /* Reload the host's PMU registers */
        ld      r3, PACALPPACAPTR(r13)  /* is the host using the PMU? */
        lbz     r4, LPPACA_PMCINUSE(r3)
@@@ -114,6 -112,15 +112,15 @@@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201
        isync
  23:
  
+       /*
+        * Reload DEC.  HDEC interrupts were disabled when
+        * we reloaded the host's LPCR value.
+        */
+       ld      r3, HSTATE_DECEXP(r13)
+       mftb    r4
+       subf    r4, r4, r3
+       mtspr   SPRN_DEC, r4
        /*
         * For external and machine check interrupts, we need
         * to call the Linux handler to process the interrupt.
@@@ -153,15 -160,76 +160,75 @@@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206
  
  13:   b       machine_check_fwnmi
  
 -
+ kvmppc_primary_no_guest:
+       /* We handle this much like a ceded vcpu */
+       /* set our bit in napping_threads */
+       ld      r5, HSTATE_KVM_VCORE(r13)
+       lbz     r7, HSTATE_PTID(r13)
+       li      r0, 1
+       sld     r0, r0, r7
+       addi    r6, r5, VCORE_NAPPING_THREADS
+ 1:    lwarx   r3, 0, r6
+       or      r3, r3, r0
+       stwcx.  r3, 0, r6
+       bne     1b
+       /* order napping_threads update vs testing entry_exit_count */
+       isync
+       li      r12, 0
+       lwz     r7, VCORE_ENTRY_EXIT(r5)
+       cmpwi   r7, 0x100
+       bge     kvm_novcpu_exit /* another thread already exiting */
+       li      r3, NAPPING_NOVCPU
+       stb     r3, HSTATE_NAPPING(r13)
+       li      r3, 1
+       stb     r3, HSTATE_HWTHREAD_REQ(r13)
+       b       kvm_do_nap
+ kvm_novcpu_wakeup:
+       ld      r1, HSTATE_HOST_R1(r13)
+       ld      r5, HSTATE_KVM_VCORE(r13)
+       li      r0, 0
+       stb     r0, HSTATE_NAPPING(r13)
+       stb     r0, HSTATE_HWTHREAD_REQ(r13)
+       /* check the wake reason */
+       bl      kvmppc_check_wake_reason
+       
+       /* see if any other thread is already exiting */
+       lwz     r0, VCORE_ENTRY_EXIT(r5)
+       cmpwi   r0, 0x100
+       bge     kvm_novcpu_exit
+       /* clear our bit in napping_threads */
+       lbz     r7, HSTATE_PTID(r13)
+       li      r0, 1
+       sld     r0, r0, r7
+       addi    r6, r5, VCORE_NAPPING_THREADS
+ 4:    lwarx   r7, 0, r6
+       andc    r7, r7, r0
+       stwcx.  r7, 0, r6
+       bne     4b
+       /* See if the wake reason means we need to exit */
+       cmpdi   r3, 0
+       bge     kvm_novcpu_exit
+       /* Got an IPI but other vcpus aren't yet exiting, must be a latecomer */
+       ld      r4, HSTATE_KVM_VCPU(r13)
+       cmpdi   r4, 0
+       bne     kvmppc_got_guest
+ kvm_novcpu_exit:
+       b       hdec_soon
  /*
-  * We come in here when wakened from nap mode on a secondary hw thread.
+  * We come in here when wakened from nap mode.
   * Relocation is off and most register values are lost.
   * r13 points to the PACA.
   */
        .globl  kvm_start_guest
  kvm_start_guest:
-       ld      r1,PACAEMERGSP(r13)
-       subi    r1,r1,STACK_FRAME_OVERHEAD
        ld      r2,PACATOC(r13)
  
        li      r0,KVM_HWTHREAD_IN_KVM
  
        /* were we napping due to cede? */
        lbz     r0,HSTATE_NAPPING(r13)
-       cmpwi   r0,0
-       bne     kvm_end_cede
+       cmpwi   r0,NAPPING_CEDE
+       beq     kvm_end_cede
+       cmpwi   r0,NAPPING_NOVCPU
+       beq     kvm_novcpu_wakeup
+       ld      r1,PACAEMERGSP(r13)
+       subi    r1,r1,STACK_FRAME_OVERHEAD
  
        /*
         * We weren't napping due to cede, so this must be a secondary
         */
  
        /* Check the wake reason in SRR1 to see why we got here */
-       mfspr   r3,SPRN_SRR1
-       rlwinm  r3,r3,44-31,0x7         /* extract wake reason field */
-       cmpwi   r3,4                    /* was it an external interrupt? */
-       bne     27f                     /* if not */
-       ld      r5,HSTATE_XICS_PHYS(r13)
-       li      r7,XICS_XIRR            /* if it was an external interrupt, */
-       lwzcix  r8,r5,r7                /* get and ack the interrupt */
-       sync
-       clrldi. r9,r8,40                /* get interrupt source ID. */
-       beq     28f                     /* none there? */
-       cmpwi   r9,XICS_IPI             /* was it an IPI? */
-       bne     29f
-       li      r0,0xff
-       li      r6,XICS_MFRR
-       stbcix  r0,r5,r6                /* clear IPI */
-       stwcix  r8,r5,r7                /* EOI the interrupt */
-       sync                            /* order loading of vcpu after that */
+       bl      kvmppc_check_wake_reason
+       cmpdi   r3, 0
+       bge     kvm_no_guest
  
        /* get vcpu pointer, NULL if we have no vcpu to run */
        ld      r4,HSTATE_KVM_VCPU(r13)
        cmpdi   r4,0
        /* if we have no vcpu to run, go back to sleep */
        beq     kvm_no_guest
-       b       30f
  
- 27:   /* XXX should handle hypervisor maintenance interrupts etc. here */
-       b       kvm_no_guest
- 28:   /* SRR1 said external but ICP said nope?? */
-       b       kvm_no_guest
- 29:   /* External non-IPI interrupt to offline secondary thread? help?? */
-       stw     r8,HSTATE_SAVED_XIRR(r13)
-       b       kvm_no_guest
+       /* Set HSTATE_DSCR(r13) to something sensible */
+       LOAD_REG_ADDR(r6, dscr_default)
+       ld      r6, 0(r6)
+       std     r6, HSTATE_DSCR(r13)
  
30:   bl      kvmppc_hv_entry
      bl      kvmppc_hv_entry
  
        /* Back from the guest, go back to nap */
        /* Clear our vcpu pointer so we don't come back in early */
        li      r0, 0
        std     r0, HSTATE_KVM_VCPU(r13)
 +      /*
 +       * Make sure we clear HSTATE_KVM_VCPU(r13) before incrementing
 +       * the nap_count, because once the increment to nap_count is
 +       * visible we could be given another vcpu.
 +       */
        lwsync
-       /* Clear any pending IPI - we're an offline thread */
-       ld      r5, HSTATE_XICS_PHYS(r13)
-       li      r7, XICS_XIRR
-       lwzcix  r3, r5, r7              /* ack any pending interrupt */
-       rlwinm. r0, r3, 0, 0xffffff     /* any pending? */
-       beq     37f
-       sync
-       li      r0, 0xff
-       li      r6, XICS_MFRR
-       stbcix  r0, r5, r6              /* clear the IPI */
-       stwcix  r3, r5, r7              /* EOI it */
- 37:   sync
  
        /* increment the nap count and then go to nap mode */
        ld      r4, HSTATE_KVM_VCORE(r13)
        addi    r4, r4, VCORE_NAP_COUNT
 -      lwsync                          /* make previous updates visible */
  51:   lwarx   r3, 0, r4
        addi    r3, r3, 1
        stwcx.  r3, 0, r4
  kvm_no_guest:
        li      r0, KVM_HWTHREAD_IN_NAP
        stb     r0, HSTATE_HWTHREAD_STATE(r13)
+ kvm_do_nap:
        li      r3, LPCR_PECE0
        mfspr   r4, SPRN_LPCR
        rlwimi  r4, r3, 0, LPCR_PECE0 | LPCR_PECE1
@@@ -277,7 -317,7 +320,7 @@@ kvmppc_hv_entry
  
        /* Required state:
         *
-        * R4 = vcpu pointer
+        * R4 = vcpu pointer (or NULL)
         * MSR = ~IR|DR
         * R13 = PACA
         * R1 = host R1
        std     r0, PPC_LR_STKOFF(r1)
        stdu    r1, -112(r1)
  
-       /* Set partition DABR */
-       /* Do this before re-enabling PMU to avoid P7 DABR corruption bug */
-       li      r5,3
-       ld      r6,VCPU_DABR(r4)
-       mtspr   SPRN_DABRX,r5
-       mtspr   SPRN_DABR,r6
- BEGIN_FTR_SECTION
-       isync
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
-       /* Load guest PMU registers */
-       /* R4 is live here (vcpu pointer) */
-       li      r3, 1
-       sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
-       mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable ints */
-       isync
-       lwz     r3, VCPU_PMC(r4)        /* always load up guest PMU registers */
-       lwz     r5, VCPU_PMC + 4(r4)    /* to prevent information leak */
-       lwz     r6, VCPU_PMC + 8(r4)
-       lwz     r7, VCPU_PMC + 12(r4)
-       lwz     r8, VCPU_PMC + 16(r4)
-       lwz     r9, VCPU_PMC + 20(r4)
- BEGIN_FTR_SECTION
-       lwz     r10, VCPU_PMC + 24(r4)
-       lwz     r11, VCPU_PMC + 28(r4)
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
-       mtspr   SPRN_PMC1, r3
-       mtspr   SPRN_PMC2, r5
-       mtspr   SPRN_PMC3, r6
-       mtspr   SPRN_PMC4, r7
-       mtspr   SPRN_PMC5, r8
-       mtspr   SPRN_PMC6, r9
- BEGIN_FTR_SECTION
-       mtspr   SPRN_PMC7, r10
-       mtspr   SPRN_PMC8, r11
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
-       ld      r3, VCPU_MMCR(r4)
-       ld      r5, VCPU_MMCR + 8(r4)
-       ld      r6, VCPU_MMCR + 16(r4)
-       ld      r7, VCPU_SIAR(r4)
-       ld      r8, VCPU_SDAR(r4)
-       mtspr   SPRN_MMCR1, r5
-       mtspr   SPRN_MMCRA, r6
-       mtspr   SPRN_SIAR, r7
-       mtspr   SPRN_SDAR, r8
-       mtspr   SPRN_MMCR0, r3
-       isync
-       /* Load up FP, VMX and VSX registers */
-       bl      kvmppc_load_fp
-       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)
- BEGIN_FTR_SECTION
-       /* Switch DSCR to guest value */
-       ld      r5, VCPU_DSCR(r4)
-       mtspr   SPRN_DSCR, r5
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
-       /*
-        * Set the decrementer to the guest decrementer.
-        */
-       ld      r8,VCPU_DEC_EXPIRES(r4)
-       mftb    r7
-       subf    r3,r7,r8
-       mtspr   SPRN_DEC,r3
-       stw     r3,VCPU_DEC(r4)
-       ld      r5, VCPU_SPRG0(r4)
-       ld      r6, VCPU_SPRG1(r4)
-       ld      r7, VCPU_SPRG2(r4)
-       ld      r8, VCPU_SPRG3(r4)
-       mtspr   SPRN_SPRG0, r5
-       mtspr   SPRN_SPRG1, r6
-       mtspr   SPRN_SPRG2, r7
-       mtspr   SPRN_SPRG3, r8
        /* Save R1 in the PACA */
        std     r1, HSTATE_HOST_R1(r13)
  
-       /* Load up DAR and DSISR */
-       ld      r5, VCPU_DAR(r4)
-       lwz     r6, VCPU_DSISR(r4)
-       mtspr   SPRN_DAR, r5
-       mtspr   SPRN_DSISR, r6
        li      r6, KVM_GUEST_MODE_HOST_HV
        stb     r6, HSTATE_IN_GUEST(r13)
  
- BEGIN_FTR_SECTION
-       /* Restore AMR and UAMOR, set AMOR to all 1s */
-       ld      r5,VCPU_AMR(r4)
-       ld      r6,VCPU_UAMOR(r4)
-       li      r7,-1
-       mtspr   SPRN_AMR,r5
-       mtspr   SPRN_UAMOR,r6
-       mtspr   SPRN_AMOR,r7
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
        /* Clear out SLB */
        li      r6,0
        slbmte  r6,r6
@@@ -428,8 -358,8 +361,8 @@@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201
        bne     21b
  
        /* Primary thread switches to guest partition. */
-       ld      r9,VCPU_KVM(r4)         /* pointer to struct kvm */
-       lwz     r6,VCPU_PTID(r4)
+       ld      r9,VCORE_KVM(r5)        /* pointer to struct kvm */
+       lbz     r6,HSTATE_PTID(r13)
        cmpwi   r6,0
        bne     20f
        ld      r6,KVM_SDR1(r9)
        andc    r7,r7,r0
        stdcx.  r7,0,r6
        bne     23b
-       li      r6,128                  /* and flush the TLB */
+       /* Flush the TLB of any entries for this LPID */
+       /* use arch 2.07S as a proxy for POWER8 */
+ BEGIN_FTR_SECTION
+       li      r6,512                  /* POWER8 has 512 sets */
+ FTR_SECTION_ELSE
+       li      r6,128                  /* POWER7 has 128 sets */
+ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_207S)
        mtctr   r6
        li      r7,0x800                /* IS field = 0b10 */
        ptesync
        beq     38f
        mtspr   SPRN_PCR, r7
  38:
+ BEGIN_FTR_SECTION
+       /* DPDES is shared between threads */
+       ld      r8, VCORE_DPDES(r5)
+       mtspr   SPRN_DPDES, r8
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
        li      r0,1
        stb     r0,VCORE_IN_GUEST(r5)   /* signal secondaries to continue */
        b       10f
        mtspr   SPRN_RMOR,r8
        isync
  
-       /* Increment yield count if they have a VPA */
-       ld      r3, VCPU_VPA(r4)
-       cmpdi   r3, 0
-       beq     25f
-       lwz     r5, LPPACA_YIELDCOUNT(r3)
-       addi    r5, r5, 1
-       stw     r5, LPPACA_YIELDCOUNT(r3)
-       li      r6, 1
-       stb     r6, VCPU_VPA_DIRTY(r4)
- 25:
        /* Check if HDEC expires soon */
        mfspr   r3,SPRN_HDEC
-       cmpwi   r3,10
+       cmpwi   r3,512          /* 1 microsecond */
        li      r12,BOOK3S_INTERRUPT_HV_DECREMENTER
-       mr      r9,r4
        blt     hdec_soon
-       /* Save purr/spurr */
-       mfspr   r5,SPRN_PURR
-       mfspr   r6,SPRN_SPURR
-       std     r5,HSTATE_PURR(r13)
-       std     r6,HSTATE_SPURR(r13)
-       ld      r7,VCPU_PURR(r4)
-       ld      r8,VCPU_SPURR(r4)
-       mtspr   SPRN_PURR,r7
-       mtspr   SPRN_SPURR,r8
        b       31f
  
        /*
         * We also have to invalidate the TLB since its
         * entries aren't tagged with the LPID.
         */
- 30:   ld      r9,VCPU_KVM(r4)         /* pointer to struct kvm */
+ 30:   ld      r5,HSTATE_KVM_VCORE(r13)
+       ld      r9,VCORE_KVM(r5)        /* pointer to struct kvm */
  
        /* first take native_tlbie_lock */
        .section ".toc","aw"
@@@ -604,7 -527,6 +530,6 @@@ toc_tlbie_lock
        mfspr   r3,SPRN_HDEC
        cmpwi   r3,10
        li      r12,BOOK3S_INTERRUPT_HV_DECREMENTER
-       mr      r9,r4
        blt     hdec_soon
  
        /* Enable HDEC interrupts */
        mfspr   r0,SPRN_HID0
        mfspr   r0,SPRN_HID0
        mfspr   r0,SPRN_HID0
+ 31:
+       /* Do we have a guest vcpu to run? */
+       cmpdi   r4, 0
+       beq     kvmppc_primary_no_guest
+ kvmppc_got_guest:
  
        /* Load up guest SLB entries */
31:   lwz     r5,VCPU_SLB_MAX(r4)
      lwz     r5,VCPU_SLB_MAX(r4)
        cmpwi   r5,0
        beq     9f
        mtctr   r5
        addi    r6,r6,VCPU_SLB_SIZE
        bdnz    1b
  9:
+       /* Increment yield count if they have a VPA */
+       ld      r3, VCPU_VPA(r4)
+       cmpdi   r3, 0
+       beq     25f
+       lwz     r5, LPPACA_YIELDCOUNT(r3)
+       addi    r5, r5, 1
+       stw     r5, LPPACA_YIELDCOUNT(r3)
+       li      r6, 1
+       stb     r6, VCPU_VPA_DIRTY(r4)
+ 25:
+ BEGIN_FTR_SECTION
+       /* Save purr/spurr */
+       mfspr   r5,SPRN_PURR
+       mfspr   r6,SPRN_SPURR
+       std     r5,HSTATE_PURR(r13)
+       std     r6,HSTATE_SPURR(r13)
+       ld      r7,VCPU_PURR(r4)
+       ld      r8,VCPU_SPURR(r4)
+       mtspr   SPRN_PURR,r7
+       mtspr   SPRN_SPURR,r8
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+ BEGIN_FTR_SECTION
+       /* Set partition DABR */
+       /* Do this before re-enabling PMU to avoid P7 DABR corruption bug */
+       lwz     r5,VCPU_DABRX(r4)
+       ld      r6,VCPU_DABR(r4)
+       mtspr   SPRN_DABRX,r5
+       mtspr   SPRN_DABR,r6
+  BEGIN_FTR_SECTION_NESTED(89)
+       isync
+  END_FTR_SECTION_NESTED(CPU_FTR_ARCH_206, CPU_FTR_ARCH_206, 89)
+ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+       /* Load guest PMU registers */
+       /* R4 is live here (vcpu pointer) */
+       li      r3, 1
+       sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
+       mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable ints */
+       isync
+       lwz     r3, VCPU_PMC(r4)        /* always load up guest PMU registers */
+       lwz     r5, VCPU_PMC + 4(r4)    /* to prevent information leak */
+       lwz     r6, VCPU_PMC + 8(r4)
+       lwz     r7, VCPU_PMC + 12(r4)
+       lwz     r8, VCPU_PMC + 16(r4)
+       lwz     r9, VCPU_PMC + 20(r4)
+ BEGIN_FTR_SECTION
+       lwz     r10, VCPU_PMC + 24(r4)
+       lwz     r11, VCPU_PMC + 28(r4)
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
+       mtspr   SPRN_PMC1, r3
+       mtspr   SPRN_PMC2, r5
+       mtspr   SPRN_PMC3, r6
+       mtspr   SPRN_PMC4, r7
+       mtspr   SPRN_PMC5, r8
+       mtspr   SPRN_PMC6, r9
+ BEGIN_FTR_SECTION
+       mtspr   SPRN_PMC7, r10
+       mtspr   SPRN_PMC8, r11
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
+       ld      r3, VCPU_MMCR(r4)
+       ld      r5, VCPU_MMCR + 8(r4)
+       ld      r6, VCPU_MMCR + 16(r4)
+       ld      r7, VCPU_SIAR(r4)
+       ld      r8, VCPU_SDAR(r4)
+       mtspr   SPRN_MMCR1, r5
+       mtspr   SPRN_MMCRA, r6
+       mtspr   SPRN_SIAR, r7
+       mtspr   SPRN_SDAR, r8
+ BEGIN_FTR_SECTION
+       ld      r5, VCPU_MMCR + 24(r4)
+       ld      r6, VCPU_SIER(r4)
+       lwz     r7, VCPU_PMC + 24(r4)
+       lwz     r8, VCPU_PMC + 28(r4)
+       ld      r9, VCPU_MMCR + 32(r4)
+       mtspr   SPRN_MMCR2, r5
+       mtspr   SPRN_SIER, r6
+       mtspr   SPRN_SPMC1, r7
+       mtspr   SPRN_SPMC2, r8
+       mtspr   SPRN_MMCRS, r9
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+       mtspr   SPRN_MMCR0, r3
+       isync
+       /* Load up FP, VMX and VSX registers */
+       bl      kvmppc_load_fp
+       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)
+ BEGIN_FTR_SECTION
+       /* Switch DSCR to guest value */
+       ld      r5, VCPU_DSCR(r4)
+       mtspr   SPRN_DSCR, r5
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+ BEGIN_FTR_SECTION
+       /* Skip next section on POWER7 or PPC970 */
+       b       8f
+ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+       /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
+       mfmsr   r8
+       li      r0, 1
+       rldimi  r8, r0, MSR_TM_LG, 63-MSR_TM_LG
+       mtmsrd  r8
+       /* Load up POWER8-specific registers */
+       ld      r5, VCPU_IAMR(r4)
+       lwz     r6, VCPU_PSPB(r4)
+       ld      r7, VCPU_FSCR(r4)
+       mtspr   SPRN_IAMR, r5
+       mtspr   SPRN_PSPB, r6
+       mtspr   SPRN_FSCR, r7
+       ld      r5, VCPU_DAWR(r4)
+       ld      r6, VCPU_DAWRX(r4)
+       ld      r7, VCPU_CIABR(r4)
+       ld      r8, VCPU_TAR(r4)
+       mtspr   SPRN_DAWR, r5
+       mtspr   SPRN_DAWRX, r6
+       mtspr   SPRN_CIABR, r7
+       mtspr   SPRN_TAR, r8
+       ld      r5, VCPU_IC(r4)
+       ld      r6, VCPU_VTB(r4)
+       mtspr   SPRN_IC, r5
+       mtspr   SPRN_VTB, r6
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       ld      r5, VCPU_TFHAR(r4)
+       ld      r6, VCPU_TFIAR(r4)
+       ld      r7, VCPU_TEXASR(r4)
+       mtspr   SPRN_TFHAR, r5
+       mtspr   SPRN_TFIAR, r6
+       mtspr   SPRN_TEXASR, r7
+ #endif
+       ld      r8, VCPU_EBBHR(r4)
+       mtspr   SPRN_EBBHR, r8
+       ld      r5, VCPU_EBBRR(r4)
+       ld      r6, VCPU_BESCR(r4)
+       ld      r7, VCPU_CSIGR(r4)
+       ld      r8, VCPU_TACR(r4)
+       mtspr   SPRN_EBBRR, r5
+       mtspr   SPRN_BESCR, r6
+       mtspr   SPRN_CSIGR, r7
+       mtspr   SPRN_TACR, r8
+       ld      r5, VCPU_TCSCR(r4)
+       ld      r6, VCPU_ACOP(r4)
+       lwz     r7, VCPU_GUEST_PID(r4)
+       ld      r8, VCPU_WORT(r4)
+       mtspr   SPRN_TCSCR, r5
+       mtspr   SPRN_ACOP, r6
+       mtspr   SPRN_PID, r7
+       mtspr   SPRN_WORT, r8
+ 8:
+       /*
+        * Set the decrementer to the guest decrementer.
+        */
+       ld      r8,VCPU_DEC_EXPIRES(r4)
+       mftb    r7
+       subf    r3,r7,r8
+       mtspr   SPRN_DEC,r3
+       stw     r3,VCPU_DEC(r4)
+       ld      r5, VCPU_SPRG0(r4)
+       ld      r6, VCPU_SPRG1(r4)
+       ld      r7, VCPU_SPRG2(r4)
+       ld      r8, VCPU_SPRG3(r4)
+       mtspr   SPRN_SPRG0, r5
+       mtspr   SPRN_SPRG1, r6
+       mtspr   SPRN_SPRG2, r7
+       mtspr   SPRN_SPRG3, r8
+       /* Load up DAR and DSISR */
+       ld      r5, VCPU_DAR(r4)
+       lwz     r6, VCPU_DSISR(r4)
+       mtspr   SPRN_DAR, r5
+       mtspr   SPRN_DSISR, r6
+ BEGIN_FTR_SECTION
+       /* Restore AMR and UAMOR, set AMOR to all 1s */
+       ld      r5,VCPU_AMR(r4)
+       ld      r6,VCPU_UAMOR(r4)
+       li      r7,-1
+       mtspr   SPRN_AMR,r5
+       mtspr   SPRN_UAMOR,r6
+       mtspr   SPRN_AMOR,r7
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
  
        /* Restore state of CTRL run bit; assume 1 on entry */
        lwz     r5,VCPU_CTRL(r4)
        mtctr   r6
        mtxer   r7
  
+ kvmppc_cede_reentry:          /* r4 = vcpu, r13 = paca */
        ld      r10, VCPU_PC(r4)
        ld      r11, VCPU_MSR(r4)
- kvmppc_cede_reentry:          /* r4 = vcpu, r13 = paca */
        ld      r6, VCPU_SRR0(r4)
        ld      r7, VCPU_SRR1(r4)
+       mtspr   SPRN_SRR0, r6
+       mtspr   SPRN_SRR1, r7
  
+ deliver_guest_interrupt:
        /* r11 = vcpu->arch.msr & ~MSR_HV */
        rldicl  r11, r11, 63 - MSR_HV_LG, 1
        rotldi  r11, r11, 1 + MSR_HV_LG
        ori     r11, r11, MSR_ME
  
        /* Check if we can deliver an external or decrementer interrupt now */
-       ld      r0,VCPU_PENDING_EXC(r4)
-       lis     r8,(1 << BOOK3S_IRQPRIO_EXTERNAL_LEVEL)@h
-       and     r0,r0,r8
-       cmpdi   cr1,r0,0
-       andi.   r0,r11,MSR_EE
-       beq     cr1,11f
+       ld      r0, VCPU_PENDING_EXC(r4)
+       rldicl  r0, r0, 64 - BOOK3S_IRQPRIO_EXTERNAL_LEVEL, 63
+       cmpdi   cr1, r0, 0
+       andi.   r8, r11, MSR_EE
  BEGIN_FTR_SECTION
-       mfspr   r8,SPRN_LPCR
-       ori     r8,r8,LPCR_MER
-       mtspr   SPRN_LPCR,r8
+       mfspr   r8, SPRN_LPCR
+       /* Insert EXTERNAL_LEVEL bit into LPCR at the MER bit position */
+       rldimi  r8, r0, LPCR_MER_SH, 63 - LPCR_MER_SH
+       mtspr   SPRN_LPCR, r8
        isync
  END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
        beq     5f
-       li      r0,BOOK3S_INTERRUPT_EXTERNAL
- 12:   mr      r6,r10
-       mr      r10,r0
-       mr      r7,r11
-       li      r11,(MSR_ME << 1) | 1   /* synthesize MSR_SF | MSR_ME */
-       rotldi  r11,r11,63
-       b       5f
- 11:   beq     5f
-       mfspr   r0,SPRN_DEC
-       cmpwi   r0,0
-       li      r0,BOOK3S_INTERRUPT_DECREMENTER
-       blt     12b
+       li      r0, BOOK3S_INTERRUPT_EXTERNAL
+       bne     cr1, 12f
+       mfspr   r0, SPRN_DEC
+       cmpwi   r0, 0
+       li      r0, BOOK3S_INTERRUPT_DECREMENTER
+       bge     5f
  
-       /* Move SRR0 and SRR1 into the respective regs */
- 5:    mtspr   SPRN_SRR0, r6
-       mtspr   SPRN_SRR1, r7
+ 12:   mtspr   SPRN_SRR0, r10
+       mr      r10,r0
+       mtspr   SPRN_SRR1, r11
+       ld      r11, VCPU_INTR_MSR(r4)
+ 5:
  
+ /*
+  * Required state:
+  * R4 = vcpu
+  * R10: value for HSRR0
+  * R11: value for HSRR1
+  * R13 = PACA
+  */
  fast_guest_return:
        li      r0,0
        stb     r0,VCPU_CEDED(r4)       /* cancel cede */
@@@ -754,14 -889,15 +892,14 @@@ kvmppc_interrupt_hv
         * guest CR, R12 saved in shadow VCPU SCRATCH1/0
         * guest R13 saved in SPRN_SCRATCH0
         */
 -      /* abuse host_r2 as third scratch area; we get r2 from PACATOC(r13) */
 -      std     r9, HSTATE_HOST_R2(r13)
 +      std     r9, HSTATE_SCRATCH2(r13)
  
        lbz     r9, HSTATE_IN_GUEST(r13)
        cmpwi   r9, KVM_GUEST_MODE_HOST_HV
        beq     kvmppc_bad_host_intr
  #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
        cmpwi   r9, KVM_GUEST_MODE_GUEST
 -      ld      r9, HSTATE_HOST_R2(r13)
 +      ld      r9, HSTATE_SCRATCH2(r13)
        beq     kvmppc_interrupt_pr
  #endif
        /* We're now back in the host but in guest MMU context */
        std     r6, VCPU_GPR(R6)(r9)
        std     r7, VCPU_GPR(R7)(r9)
        std     r8, VCPU_GPR(R8)(r9)
 -      ld      r0, HSTATE_HOST_R2(r13)
 +      ld      r0, HSTATE_SCRATCH2(r13)
        std     r0, VCPU_GPR(R9)(r9)
        std     r10, VCPU_GPR(R10)(r9)
        std     r11, VCPU_GPR(R11)(r9)
@@@ -868,39 -1004,19 +1006,19 @@@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206
        /* External interrupt, first check for host_ipi. If this is
         * set, we know the host wants us out so let's do it now
         */
- do_ext_interrupt:
        bl      kvmppc_read_intr
        cmpdi   r3, 0
        bgt     ext_interrupt_to_host
  
-       /* Allright, looks like an IPI for the guest, we need to set MER */
        /* Check if any CPU is heading out to the host, if so head out too */
        ld      r5, HSTATE_KVM_VCORE(r13)
        lwz     r0, VCORE_ENTRY_EXIT(r5)
        cmpwi   r0, 0x100
        bge     ext_interrupt_to_host
  
-       /* See if there is a pending interrupt for the guest */
-       mfspr   r8, SPRN_LPCR
-       ld      r0, VCPU_PENDING_EXC(r9)
-       /* Insert EXTERNAL_LEVEL bit into LPCR at the MER bit position */
-       rldicl. r0, r0, 64 - BOOK3S_IRQPRIO_EXTERNAL_LEVEL, 63
-       rldimi  r8, r0, LPCR_MER_SH, 63 - LPCR_MER_SH
-       beq     2f
-       /* And if the guest EE is set, we can deliver immediately, else
-        * we return to the guest with MER set
-        */
-       andi.   r0, r11, MSR_EE
-       beq     2f
-       mtspr   SPRN_SRR0, r10
-       mtspr   SPRN_SRR1, r11
-       li      r10, BOOK3S_INTERRUPT_EXTERNAL
-       li      r11, (MSR_ME << 1) | 1  /* synthesize MSR_SF | MSR_ME */
-       rotldi  r11, r11, 63
- 2:    mr      r4, r9
-       mtspr   SPRN_LPCR, r8
-       b       fast_guest_return
+       /* Return to guest after delivering any pending interrupt */
+       mr      r4, r9
+       b       deliver_guest_interrupt
  
  ext_interrupt_to_host:
  
@@@ -963,25 -1079,206 +1081,206 @@@ BEGIN_FTR_SECTIO
        subf    r5,r7,r5
        subf    r6,r8,r6
  
-       /*
-        * Restore host PURR/SPURR and add guest times
-        * so that the time in the guest gets accounted.
-        */
-       ld      r3,HSTATE_PURR(r13)
-       ld      r4,HSTATE_SPURR(r13)
-       add     r3,r3,r5
-       add     r4,r4,r6
-       mtspr   SPRN_PURR,r3
-       mtspr   SPRN_SPURR,r4
- END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_201)
+       /*
+        * Restore host PURR/SPURR and add guest times
+        * so that the time in the guest gets accounted.
+        */
+       ld      r3,HSTATE_PURR(r13)
+       ld      r4,HSTATE_SPURR(r13)
+       add     r3,r3,r5
+       add     r4,r4,r6
+       mtspr   SPRN_PURR,r3
+       mtspr   SPRN_SPURR,r4
+ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_201)
+       /* Save DEC */
+       mfspr   r5,SPRN_DEC
+       mftb    r6
+       extsw   r5,r5
+       add     r5,r5,r6
+       std     r5,VCPU_DEC_EXPIRES(r9)
+ BEGIN_FTR_SECTION
+       b       8f
+ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+       /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
+       mfmsr   r8
+       li      r0, 1
+       rldimi  r8, r0, MSR_TM_LG, 63-MSR_TM_LG
+       mtmsrd  r8
+       /* Save POWER8-specific registers */
+       mfspr   r5, SPRN_IAMR
+       mfspr   r6, SPRN_PSPB
+       mfspr   r7, SPRN_FSCR
+       std     r5, VCPU_IAMR(r9)
+       stw     r6, VCPU_PSPB(r9)
+       std     r7, VCPU_FSCR(r9)
+       mfspr   r5, SPRN_IC
+       mfspr   r6, SPRN_VTB
+       mfspr   r7, SPRN_TAR
+       std     r5, VCPU_IC(r9)
+       std     r6, VCPU_VTB(r9)
+       std     r7, VCPU_TAR(r9)
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       mfspr   r5, SPRN_TFHAR
+       mfspr   r6, SPRN_TFIAR
+       mfspr   r7, SPRN_TEXASR
+       std     r5, VCPU_TFHAR(r9)
+       std     r6, VCPU_TFIAR(r9)
+       std     r7, VCPU_TEXASR(r9)
+ #endif
+       mfspr   r8, SPRN_EBBHR
+       std     r8, VCPU_EBBHR(r9)
+       mfspr   r5, SPRN_EBBRR
+       mfspr   r6, SPRN_BESCR
+       mfspr   r7, SPRN_CSIGR
+       mfspr   r8, SPRN_TACR
+       std     r5, VCPU_EBBRR(r9)
+       std     r6, VCPU_BESCR(r9)
+       std     r7, VCPU_CSIGR(r9)
+       std     r8, VCPU_TACR(r9)
+       mfspr   r5, SPRN_TCSCR
+       mfspr   r6, SPRN_ACOP
+       mfspr   r7, SPRN_PID
+       mfspr   r8, SPRN_WORT
+       std     r5, VCPU_TCSCR(r9)
+       std     r6, VCPU_ACOP(r9)
+       stw     r7, VCPU_GUEST_PID(r9)
+       std     r8, VCPU_WORT(r9)
+ 8:
+       /* Save and reset AMR and UAMOR before turning on the MMU */
+ BEGIN_FTR_SECTION
+       mfspr   r5,SPRN_AMR
+       mfspr   r6,SPRN_UAMOR
+       std     r5,VCPU_AMR(r9)
+       std     r6,VCPU_UAMOR(r9)
+       li      r6,0
+       mtspr   SPRN_AMR,r6
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+       /* Switch DSCR back to host value */
+ BEGIN_FTR_SECTION
+       mfspr   r8, SPRN_DSCR
+       ld      r7, HSTATE_DSCR(r13)
+       std     r8, VCPU_DSCR(r9)
+       mtspr   SPRN_DSCR, r7
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+       /* Save non-volatile GPRs */
+       std     r14, VCPU_GPR(R14)(r9)
+       std     r15, VCPU_GPR(R15)(r9)
+       std     r16, VCPU_GPR(R16)(r9)
+       std     r17, VCPU_GPR(R17)(r9)
+       std     r18, VCPU_GPR(R18)(r9)
+       std     r19, VCPU_GPR(R19)(r9)
+       std     r20, VCPU_GPR(R20)(r9)
+       std     r21, VCPU_GPR(R21)(r9)
+       std     r22, VCPU_GPR(R22)(r9)
+       std     r23, VCPU_GPR(R23)(r9)
+       std     r24, VCPU_GPR(R24)(r9)
+       std     r25, VCPU_GPR(R25)(r9)
+       std     r26, VCPU_GPR(R26)(r9)
+       std     r27, VCPU_GPR(R27)(r9)
+       std     r28, VCPU_GPR(R28)(r9)
+       std     r29, VCPU_GPR(R29)(r9)
+       std     r30, VCPU_GPR(R30)(r9)
+       std     r31, VCPU_GPR(R31)(r9)
+       /* Save SPRGs */
+       mfspr   r3, SPRN_SPRG0
+       mfspr   r4, SPRN_SPRG1
+       mfspr   r5, SPRN_SPRG2
+       mfspr   r6, SPRN_SPRG3
+       std     r3, VCPU_SPRG0(r9)
+       std     r4, VCPU_SPRG1(r9)
+       std     r5, VCPU_SPRG2(r9)
+       std     r6, VCPU_SPRG3(r9)
+       /* save FP state */
+       mr      r3, r9
+       bl      kvmppc_save_fp
  
+       /* Increment yield count if they have a VPA */
+       ld      r8, VCPU_VPA(r9)        /* do they have a VPA? */
+       cmpdi   r8, 0
+       beq     25f
+       lwz     r3, LPPACA_YIELDCOUNT(r8)
+       addi    r3, r3, 1
+       stw     r3, LPPACA_YIELDCOUNT(r8)
+       li      r3, 1
+       stb     r3, VCPU_VPA_DIRTY(r9)
+ 25:
+       /* Save PMU registers if requested */
+       /* r8 and cr0.eq are live here */
+       li      r3, 1
+       sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
+       mfspr   r4, SPRN_MMCR0          /* save MMCR0 */
+       mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable ints */
+       mfspr   r6, SPRN_MMCRA
+ BEGIN_FTR_SECTION
+       /* On P7, clear MMCRA in order to disable SDAR updates */
+       li      r7, 0
+       mtspr   SPRN_MMCRA, r7
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+       isync
+       beq     21f                     /* if no VPA, save PMU stuff anyway */
+       lbz     r7, LPPACA_PMCINUSE(r8)
+       cmpwi   r7, 0                   /* did they ask for PMU stuff to be saved? */
+       bne     21f
+       std     r3, VCPU_MMCR(r9)       /* if not, set saved MMCR0 to FC */
+       b       22f
+ 21:   mfspr   r5, SPRN_MMCR1
+       mfspr   r7, SPRN_SIAR
+       mfspr   r8, SPRN_SDAR
+       std     r4, VCPU_MMCR(r9)
+       std     r5, VCPU_MMCR + 8(r9)
+       std     r6, VCPU_MMCR + 16(r9)
+       std     r7, VCPU_SIAR(r9)
+       std     r8, VCPU_SDAR(r9)
+       mfspr   r3, SPRN_PMC1
+       mfspr   r4, SPRN_PMC2
+       mfspr   r5, SPRN_PMC3
+       mfspr   r6, SPRN_PMC4
+       mfspr   r7, SPRN_PMC5
+       mfspr   r8, SPRN_PMC6
+ BEGIN_FTR_SECTION
+       mfspr   r10, SPRN_PMC7
+       mfspr   r11, SPRN_PMC8
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
+       stw     r3, VCPU_PMC(r9)
+       stw     r4, VCPU_PMC + 4(r9)
+       stw     r5, VCPU_PMC + 8(r9)
+       stw     r6, VCPU_PMC + 12(r9)
+       stw     r7, VCPU_PMC + 16(r9)
+       stw     r8, VCPU_PMC + 20(r9)
+ BEGIN_FTR_SECTION
+       stw     r10, VCPU_PMC + 24(r9)
+       stw     r11, VCPU_PMC + 28(r9)
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
+ BEGIN_FTR_SECTION
+       mfspr   r4, SPRN_MMCR2
+       mfspr   r5, SPRN_SIER
+       mfspr   r6, SPRN_SPMC1
+       mfspr   r7, SPRN_SPMC2
+       mfspr   r8, SPRN_MMCRS
+       std     r4, VCPU_MMCR + 24(r9)
+       std     r5, VCPU_SIER(r9)
+       stw     r6, VCPU_PMC + 24(r9)
+       stw     r7, VCPU_PMC + 28(r9)
+       std     r8, VCPU_MMCR + 32(r9)
+       lis     r4, 0x8000
+       mtspr   SPRN_MMCRS, r4
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+ 22:
        /* Clear out SLB */
        li      r5,0
        slbmte  r5,r5
        slbia
        ptesync
  
- hdec_soon:                    /* r9 = vcpu, r12 = trap, r13 = paca */
+ hdec_soon:                    /* r12 = trap, r13 = paca */
  BEGIN_FTR_SECTION
        b       32f
  END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
         */
        /* Increment the threads-exiting-guest count in the 0xff00
           bits of vcore->entry_exit_count */
 -      lwsync
        ld      r5,HSTATE_KVM_VCORE(r13)
        addi    r6,r5,VCORE_ENTRY_EXIT
  41:   lwarx   r3,0,r6
        addi    r0,r3,0x100
        stwcx.  r0,0,r6
        bne     41b
 -      lwsync
 +      isync           /* order stwcx. vs. reading napping_threads */
  
        /*
         * At this point we have an interrupt that we have to pass
         */
        cmpwi   r3,0x100        /* Are we the first here? */
        bge     43f
-       cmpwi   r3,1            /* Are any other threads in the guest? */
-       ble     43f
        cmpwi   r12,BOOK3S_INTERRUPT_HV_DECREMENTER
        beq     40f
        li      r0,0
         * doesn't wake CPUs up from nap.
         */
        lwz     r3,VCORE_NAPPING_THREADS(r5)
-       lwz     r4,VCPU_PTID(r9)
+       lbz     r4,HSTATE_PTID(r13)
        li      r0,1
        sld     r0,r0,r4
        andc.   r3,r3,r0                /* no sense IPI'ing ourselves */
        beq     43f
 +      /* Order entry/exit update vs. IPIs */
 +      sync
        mulli   r4,r4,PACA_SIZE         /* get paca for thread 0 */
        subf    r6,r4,r13
  42:   andi.   r0,r3,1
        addi    r6,r6,PACA_SIZE
        bne     42b
  
+ secondary_too_late:
        /* Secondary threads wait for primary to do partition switch */
- 43:   ld      r4,VCPU_KVM(r9)         /* pointer to struct kvm */
-       ld      r5,HSTATE_KVM_VCORE(r13)
-       lwz     r3,VCPU_PTID(r9)
+ 43:   ld      r5,HSTATE_KVM_VCORE(r13)
+       ld      r4,VCORE_KVM(r5)        /* pointer to struct kvm */
+       lbz     r3,HSTATE_PTID(r13)
        cmpwi   r3,0
        beq     15f
        HMT_LOW
        mtspr   SPRN_LPID,r7
        isync
  
+ BEGIN_FTR_SECTION
+       /* DPDES is shared between threads */
+       mfspr   r7, SPRN_DPDES
+       std     r7, VCORE_DPDES(r5)
+       /* clear DPDES so we don't get guest doorbells in the host */
+       li      r8, 0
+       mtspr   SPRN_DPDES, r8
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
        /* Subtract timebase offset from timebase */
        ld      r8,VCORE_TB_OFFSET(r5)
        cmpdi   r8,0
         * We have to lock against concurrent tlbies, and
         * we have to flush the whole TLB.
         */
- 32:   ld      r4,VCPU_KVM(r9)         /* pointer to struct kvm */
+ 32:   ld      r5,HSTATE_KVM_VCORE(r13)
+       ld      r4,VCORE_KVM(r5)        /* pointer to struct kvm */
  
        /* Take the guest's tlbie_lock */
  #ifdef __BIG_ENDIAN__
        add     r5,r5,r6
        std     r5,VCPU_DEC_EXPIRES(r9)
  
+ BEGIN_FTR_SECTION
+       b       8f
+ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+       /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
+       mfmsr   r8
+       li      r0, 1
+       rldimi  r8, r0, MSR_TM_LG, 63-MSR_TM_LG
+       mtmsrd  r8
+       /* Save POWER8-specific registers */
+       mfspr   r5, SPRN_IAMR
+       mfspr   r6, SPRN_PSPB
+       mfspr   r7, SPRN_FSCR
+       std     r5, VCPU_IAMR(r9)
+       stw     r6, VCPU_PSPB(r9)
+       std     r7, VCPU_FSCR(r9)
+       mfspr   r5, SPRN_IC
+       mfspr   r6, SPRN_VTB
+       mfspr   r7, SPRN_TAR
+       std     r5, VCPU_IC(r9)
+       std     r6, VCPU_VTB(r9)
+       std     r7, VCPU_TAR(r9)
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       mfspr   r5, SPRN_TFHAR
+       mfspr   r6, SPRN_TFIAR
+       mfspr   r7, SPRN_TEXASR
+       std     r5, VCPU_TFHAR(r9)
+       std     r6, VCPU_TFIAR(r9)
+       std     r7, VCPU_TEXASR(r9)
+ #endif
+       mfspr   r8, SPRN_EBBHR
+       std     r8, VCPU_EBBHR(r9)
+       mfspr   r5, SPRN_EBBRR
+       mfspr   r6, SPRN_BESCR
+       mfspr   r7, SPRN_CSIGR
+       mfspr   r8, SPRN_TACR
+       std     r5, VCPU_EBBRR(r9)
+       std     r6, VCPU_BESCR(r9)
+       std     r7, VCPU_CSIGR(r9)
+       std     r8, VCPU_TACR(r9)
+       mfspr   r5, SPRN_TCSCR
+       mfspr   r6, SPRN_ACOP
+       mfspr   r7, SPRN_PID
+       mfspr   r8, SPRN_WORT
+       std     r5, VCPU_TCSCR(r9)
+       std     r6, VCPU_ACOP(r9)
+       stw     r7, VCPU_GUEST_PID(r9)
+       std     r8, VCPU_WORT(r9)
+ 8:
        /* Save and reset AMR and UAMOR before turning on the MMU */
  BEGIN_FTR_SECTION
        mfspr   r5,SPRN_AMR
@@@ -1217,130 -1572,10 +1575,10 @@@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206
        li      r0, KVM_GUEST_MODE_NONE
        stb     r0, HSTATE_IN_GUEST(r13)
  
-       /* Switch DSCR back to host value */
- BEGIN_FTR_SECTION
-       mfspr   r8, SPRN_DSCR
-       ld      r7, HSTATE_DSCR(r13)
-       std     r8, VCPU_DSCR(r9)
-       mtspr   SPRN_DSCR, r7
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
-       /* Save non-volatile GPRs */
-       std     r14, VCPU_GPR(R14)(r9)
-       std     r15, VCPU_GPR(R15)(r9)
-       std     r16, VCPU_GPR(R16)(r9)
-       std     r17, VCPU_GPR(R17)(r9)
-       std     r18, VCPU_GPR(R18)(r9)
-       std     r19, VCPU_GPR(R19)(r9)
-       std     r20, VCPU_GPR(R20)(r9)
-       std     r21, VCPU_GPR(R21)(r9)
-       std     r22, VCPU_GPR(R22)(r9)
-       std     r23, VCPU_GPR(R23)(r9)
-       std     r24, VCPU_GPR(R24)(r9)
-       std     r25, VCPU_GPR(R25)(r9)
-       std     r26, VCPU_GPR(R26)(r9)
-       std     r27, VCPU_GPR(R27)(r9)
-       std     r28, VCPU_GPR(R28)(r9)
-       std     r29, VCPU_GPR(R29)(r9)
-       std     r30, VCPU_GPR(R30)(r9)
-       std     r31, VCPU_GPR(R31)(r9)
-       /* Save SPRGs */
-       mfspr   r3, SPRN_SPRG0
-       mfspr   r4, SPRN_SPRG1
-       mfspr   r5, SPRN_SPRG2
-       mfspr   r6, SPRN_SPRG3
-       std     r3, VCPU_SPRG0(r9)
-       std     r4, VCPU_SPRG1(r9)
-       std     r5, VCPU_SPRG2(r9)
-       std     r6, VCPU_SPRG3(r9)
-       /* save FP state */
-       mr      r3, r9
-       bl      .kvmppc_save_fp
-       /* Increment yield count if they have a VPA */
-       ld      r8, VCPU_VPA(r9)        /* do they have a VPA? */
-       cmpdi   r8, 0
-       beq     25f
-       lwz     r3, LPPACA_YIELDCOUNT(r8)
-       addi    r3, r3, 1
-       stw     r3, LPPACA_YIELDCOUNT(r8)
-       li      r3, 1
-       stb     r3, VCPU_VPA_DIRTY(r9)
- 25:
-       /* Save PMU registers if requested */
-       /* r8 and cr0.eq are live here */
-       li      r3, 1
-       sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
-       mfspr   r4, SPRN_MMCR0          /* save MMCR0 */
-       mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable ints */
-       mfspr   r6, SPRN_MMCRA
- BEGIN_FTR_SECTION
-       /* On P7, clear MMCRA in order to disable SDAR updates */
-       li      r7, 0
-       mtspr   SPRN_MMCRA, r7
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
-       isync
-       beq     21f                     /* if no VPA, save PMU stuff anyway */
-       lbz     r7, LPPACA_PMCINUSE(r8)
-       cmpwi   r7, 0                   /* did they ask for PMU stuff to be saved? */
-       bne     21f
-       std     r3, VCPU_MMCR(r9)       /* if not, set saved MMCR0 to FC */
-       b       22f
- 21:   mfspr   r5, SPRN_MMCR1
-       mfspr   r7, SPRN_SIAR
-       mfspr   r8, SPRN_SDAR
-       std     r4, VCPU_MMCR(r9)
-       std     r5, VCPU_MMCR + 8(r9)
-       std     r6, VCPU_MMCR + 16(r9)
-       std     r7, VCPU_SIAR(r9)
-       std     r8, VCPU_SDAR(r9)
-       mfspr   r3, SPRN_PMC1
-       mfspr   r4, SPRN_PMC2
-       mfspr   r5, SPRN_PMC3
-       mfspr   r6, SPRN_PMC4
-       mfspr   r7, SPRN_PMC5
-       mfspr   r8, SPRN_PMC6
- BEGIN_FTR_SECTION
-       mfspr   r10, SPRN_PMC7
-       mfspr   r11, SPRN_PMC8
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
-       stw     r3, VCPU_PMC(r9)
-       stw     r4, VCPU_PMC + 4(r9)
-       stw     r5, VCPU_PMC + 8(r9)
-       stw     r6, VCPU_PMC + 12(r9)
-       stw     r7, VCPU_PMC + 16(r9)
-       stw     r8, VCPU_PMC + 20(r9)
- BEGIN_FTR_SECTION
-       stw     r10, VCPU_PMC + 24(r9)
-       stw     r11, VCPU_PMC + 28(r9)
- END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
- 22:
        ld      r0, 112+PPC_LR_STKOFF(r1)
        addi    r1, r1, 112
        mtlr    r0
        blr
- secondary_too_late:
-       ld      r5,HSTATE_KVM_VCORE(r13)
-       HMT_LOW
- 13:   lbz     r3,VCORE_IN_GUEST(r5)
-       cmpwi   r3,0
-       bne     13b
-       HMT_MEDIUM
-       li      r0, KVM_GUEST_MODE_NONE
-       stb     r0, HSTATE_IN_GUEST(r13)
-       ld      r11,PACA_SLBSHADOWPTR(r13)
-       .rept   SLB_NUM_BOLTED
-       ld      r5,SLBSHADOW_SAVEAREA(r11)
-       ld      r6,SLBSHADOW_SAVEAREA+8(r11)
-       andis.  r7,r5,SLB_ESID_V@h
-       beq     1f
-       slbmte  r6,r5
- 1:    addi    r11,r11,16
-       .endr
-       b       22b
  
  /*
   * Check whether an HDSI is an HPTE not found fault or something else.
@@@ -1386,8 -1621,7 +1624,7 @@@ kvmppc_hdsi
        mtspr   SPRN_SRR0, r10
        mtspr   SPRN_SRR1, r11
        li      r10, BOOK3S_INTERRUPT_DATA_STORAGE
-       li      r11, (MSR_ME << 1) | 1  /* synthesize MSR_SF | MSR_ME */
-       rotldi  r11, r11, 63
+       ld      r11, VCPU_INTR_MSR(r9)
  fast_interrupt_c_return:
  6:    ld      r7, VCPU_CTR(r9)
        lwz     r8, VCPU_XER(r9)
@@@ -1456,8 -1690,7 +1693,7 @@@ kvmppc_hisi
  1:    mtspr   SPRN_SRR0, r10
        mtspr   SPRN_SRR1, r11
        li      r10, BOOK3S_INTERRUPT_INST_STORAGE
-       li      r11, (MSR_ME << 1) | 1  /* synthesize MSR_SF | MSR_ME */
-       rotldi  r11, r11, 63
+       ld      r11, VCPU_INTR_MSR(r9)
        b       fast_interrupt_c_return
  
  3:    ld      r6, VCPU_KVM(r9)        /* not relocated, use VRMA */
  hcall_try_real_mode:
        ld      r3,VCPU_GPR(R3)(r9)
        andi.   r0,r11,MSR_PR
-       bne     guest_exit_cont
+       /* sc 1 from userspace - reflect to guest syscall */
+       bne     sc_1_fast_return
        clrrdi  r3,r3,2
        cmpldi  r3,hcall_real_table_end - hcall_real_table
        bge     guest_exit_cont
        ld      r11,VCPU_MSR(r4)
        b       fast_guest_return
  
+ sc_1_fast_return:
+       mtspr   SPRN_SRR0,r10
+       mtspr   SPRN_SRR1,r11
+       li      r10, BOOK3S_INTERRUPT_SYSCALL
+       ld      r11, VCPU_INTR_MSR(r9)
+       mr      r4,r9
+       b       fast_guest_return
        /* We've attempted a real mode hcall, but it's punted it back
         * to userspace.  We need to restore some clobbered volatiles
         * before resuming the pass-it-to-qemu path */
@@@ -1588,14 -1830,34 +1833,34 @@@ hcall_real_table
        .long   0               /* 0x11c */
        .long   0               /* 0x120 */
        .long   .kvmppc_h_bulk_remove - hcall_real_table
+       .long   0               /* 0x128 */
+       .long   0               /* 0x12c */
+       .long   0               /* 0x130 */
+       .long   .kvmppc_h_set_xdabr - hcall_real_table
  hcall_real_table_end:
  
  ignore_hdec:
        mr      r4,r9
        b       fast_guest_return
  
+ _GLOBAL(kvmppc_h_set_xdabr)
+       andi.   r0, r5, DABRX_USER | DABRX_KERNEL
+       beq     6f
+       li      r0, DABRX_USER | DABRX_KERNEL | DABRX_BTI
+       andc.   r0, r5, r0
+       beq     3f
+ 6:    li      r3, H_PARAMETER
+       blr
  _GLOBAL(kvmppc_h_set_dabr)
+       li      r5, DABRX_USER | DABRX_KERNEL
+ 3:
+ BEGIN_FTR_SECTION
+       b       2f
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
        std     r4,VCPU_DABR(r3)
+       stw     r5, VCPU_DABRX(r3)
+       mtspr   SPRN_DABRX, r5
        /* Work around P7 bug where DABR can get corrupted on mtspr */
  1:    mtspr   SPRN_DABR,r4
        mfspr   r5, SPRN_DABR
        li      r3,0
        blr
  
+       /* Emulate H_SET_DABR/X on P8 for the sake of compat mode guests */
+ 2:    rlwimi  r5, r4, 5, DAWRX_DR | DAWRX_DW
+       rlwimi  r5, r4, 1, DAWRX_WT
+       clrrdi  r4, r4, 3
+       std     r4, VCPU_DAWR(r3)
+       std     r5, VCPU_DAWRX(r3)
+       mtspr   SPRN_DAWR, r4
+       mtspr   SPRN_DAWRX, r5
+       li      r3, 0
+       blr
  _GLOBAL(kvmppc_h_cede)
        ori     r11,r11,MSR_EE
        std     r11,VCPU_MSR(r3)
@@@ -1628,7 -1901,7 +1904,7 @@@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206
         * up to the host.
         */
        ld      r5,HSTATE_KVM_VCORE(r13)
-       lwz     r6,VCPU_PTID(r3)
+       lbz     r6,HSTATE_PTID(r13)
        lwz     r8,VCORE_ENTRY_EXIT(r5)
        clrldi  r8,r8,56
        li      r0,1
        bge     kvm_cede_exit
        stwcx.  r4,0,r6
        bne     31b
-       li      r0,1
 +      /* order napping_threads update vs testing entry_exit_count */
 +      isync
+       li      r0,NAPPING_CEDE
        stb     r0,HSTATE_NAPPING(r13)
-       mr      r4,r3
 -      /* order napping_threads update vs testing entry_exit_count */
 -      lwsync
        lwz     r7,VCORE_ENTRY_EXIT(r5)
        cmpwi   r7,0x100
        bge     33f             /* another thread already exiting */
        std     r31, VCPU_GPR(R31)(r3)
  
        /* save FP state */
-       bl      .kvmppc_save_fp
+       bl      kvmppc_save_fp
  
        /*
-        * Take a nap until a decrementer or external interrupt occurs,
-        * with PECE1 (wake on decr) and PECE0 (wake on external) set in LPCR
+        * Take a nap until a decrementer or external or doobell interrupt
+        * occurs, with PECE1, PECE0 and PECEDP set in LPCR
         */
        li      r0,1
        stb     r0,HSTATE_HWTHREAD_REQ(r13)
        mfspr   r5,SPRN_LPCR
        ori     r5,r5,LPCR_PECE0 | LPCR_PECE1
+ BEGIN_FTR_SECTION
+       oris    r5,r5,LPCR_PECEDP@h
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
        mtspr   SPRN_LPCR,r5
        isync
        li      r0, 0
        nap
        b       .
  
+ 33:   mr      r4, r3
+       li      r3, 0
+       li      r12, 0
+       b       34f
  kvm_end_cede:
        /* get vcpu pointer */
        ld      r4, HSTATE_KVM_VCPU(r13)
        ld      r29, VCPU_GPR(R29)(r4)
        ld      r30, VCPU_GPR(R30)(r4)
        ld      r31, VCPU_GPR(R31)(r4)
+  
+       /* Check the wake reason in SRR1 to see why we got here */
+       bl      kvmppc_check_wake_reason
  
        /* clear our bit in vcore->napping_threads */
- 33:   ld      r5,HSTATE_KVM_VCORE(r13)
-       lwz     r3,VCPU_PTID(r4)
+ 34:   ld      r5,HSTATE_KVM_VCORE(r13)
+       lbz     r7,HSTATE_PTID(r13)
        li      r0,1
-       sld     r0,r0,r3
+       sld     r0,r0,r7
        addi    r6,r5,VCORE_NAPPING_THREADS
  32:   lwarx   r7,0,r6
        andc    r7,r7,r0
        li      r0,0
        stb     r0,HSTATE_NAPPING(r13)
  
-       /* Check the wake reason in SRR1 to see why we got here */
-       mfspr   r3, SPRN_SRR1
-       rlwinm  r3, r3, 44-31, 0x7      /* extract wake reason field */
-       cmpwi   r3, 4                   /* was it an external interrupt? */
-       li      r12, BOOK3S_INTERRUPT_EXTERNAL
+       /* See if the wake reason means we need to exit */
+       stw     r12, VCPU_TRAP(r4)
        mr      r9, r4
-       ld      r10, VCPU_PC(r9)
-       ld      r11, VCPU_MSR(r9)
-       beq     do_ext_interrupt        /* if so */
+       cmpdi   r3, 0
+       bgt     guest_exit_cont
  
        /* see if any other thread is already exiting */
        lwz     r0,VCORE_ENTRY_EXIT(r5)
        cmpwi   r0,0x100
-       blt     kvmppc_cede_reentry     /* if not go back to guest */
+       bge     guest_exit_cont
  
-       /* some threads are exiting, so go to the guest exit path */
-       b       hcall_real_fallback
+       b       kvmppc_cede_reentry     /* if not go back to guest */
  
        /* cede when already previously prodded case */
  kvm_cede_prodded:
@@@ -1783,10 -2061,47 +2064,47 @@@ machine_check_realmode
        beq     mc_cont
        /* If not, deliver a machine check.  SRR0/1 are already set */
        li      r10, BOOK3S_INTERRUPT_MACHINE_CHECK
-       li      r11, (MSR_ME << 1) | 1  /* synthesize MSR_SF | MSR_ME */
-       rotldi  r11, r11, 63
+       ld      r11, VCPU_INTR_MSR(r9)
        b       fast_interrupt_c_return
  
+ /*
+  * Check the reason we woke from nap, and take appropriate action.
+  * Returns:
+  *    0 if nothing needs to be done
+  *    1 if something happened that needs to be handled by the host
+  *    -1 if there was a guest wakeup (IPI)
+  *
+  * Also sets r12 to the interrupt vector for any interrupt that needs
+  * to be handled now by the host (0x500 for external interrupt), or zero.
+  */
+ kvmppc_check_wake_reason:
+       mfspr   r6, SPRN_SRR1
+ BEGIN_FTR_SECTION
+       rlwinm  r6, r6, 45-31, 0xf      /* extract wake reason field (P8) */
+ FTR_SECTION_ELSE
+       rlwinm  r6, r6, 45-31, 0xe      /* P7 wake reason field is 3 bits */
+ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_207S)
+       cmpwi   r6, 8                   /* was it an external interrupt? */
+       li      r12, BOOK3S_INTERRUPT_EXTERNAL
+       beq     kvmppc_read_intr        /* if so, see what it was */
+       li      r3, 0
+       li      r12, 0
+       cmpwi   r6, 6                   /* was it the decrementer? */
+       beq     0f
+ BEGIN_FTR_SECTION
+       cmpwi   r6, 5                   /* privileged doorbell? */
+       beq     0f
+       cmpwi   r6, 3                   /* hypervisor doorbell? */
+       beq     3f
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+       li      r3, 1                   /* anything else, return 1 */
+ 0:    blr
+       /* hypervisor doorbell */
+ 3:    li      r12, BOOK3S_INTERRUPT_H_DOORBELL
+       li      r3, 1
+       blr
  /*
   * Determine what sort of external interrupt is pending (if any).
   * Returns:
@@@ -1818,7 -2133,6 +2136,6 @@@ kvmppc_read_intr
         * interrupts directly to the guest
         */
        cmpwi   r3, XICS_IPI            /* if there is, is it an IPI? */
-       li      r3, 1
        bne     42f
  
        /* It's an IPI, clear the MFRR and EOI it */
         * before exit, it will be picked up by the host ICP driver
         */
        stw     r0, HSTATE_SAVED_XIRR(r13)
+       li      r3, 1
        b       1b
  
  43:   /* We raced with the host, we need to resend that IPI, bummer */
        li      r0, IPI_PRIORITY
        stbcix  r0, r6, r8              /* set the IPI */
        sync
+       li      r3, 1
        b       1b
  
  /*
   * Save away FP, VMX and VSX registers.
   * r3 = vcpu pointer
+  * N.B. r30 and r31 are volatile across this function,
+  * thus it is not callable from C.
   */
- _GLOBAL(kvmppc_save_fp)
+ kvmppc_save_fp:
+       mflr    r30
+       mr      r31,r3
        mfmsr   r5
        ori     r8,r5,MSR_FP
  #ifdef CONFIG_ALTIVEC
@@@ -1871,42 -2191,17 +2194,17 @@@ END_FTR_SECTION_IFSET(CPU_FTR_VSX
  #endif
        mtmsrd  r8
        isync
- #ifdef CONFIG_VSX
- BEGIN_FTR_SECTION
-       reg = 0
-       .rept   32
-       li      r6,reg*16+VCPU_VSRS
-       STXVD2X(reg,R6,R3)
-       reg = reg + 1
-       .endr
- FTR_SECTION_ELSE
- #endif
-       reg = 0
-       .rept   32
-       stfd    reg,reg*8+VCPU_FPRS(r3)
-       reg = reg + 1
-       .endr
- #ifdef CONFIG_VSX
- ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
- #endif
-       mffs    fr0
-       stfd    fr0,VCPU_FPSCR(r3)
+       addi    r3,r3,VCPU_FPRS
+       bl      .store_fp_state
  #ifdef CONFIG_ALTIVEC
  BEGIN_FTR_SECTION
-       reg = 0
-       .rept   32
-       li      r6,reg*16+VCPU_VRS
-       stvx    reg,r6,r3
-       reg = reg + 1
-       .endr
-       mfvscr  vr0
-       li      r6,VCPU_VSCR
-       stvx    vr0,r6,r3
+       addi    r3,r31,VCPU_VRS
+       bl      .store_vr_state
  END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  #endif
        mfspr   r6,SPRN_VRSAVE
        stw     r6,VCPU_VRSAVE(r3)
+       mtlr    r30
        mtmsrd  r5
        isync
        blr
  /*
   * Load up FP, VMX and VSX registers
   * r4 = vcpu pointer
+  * N.B. r30 and r31 are volatile across this function,
+  * thus it is not callable from C.
   */
-       .globl  kvmppc_load_fp
  kvmppc_load_fp:
+       mflr    r30
+       mr      r31,r4
        mfmsr   r9
        ori     r8,r9,MSR_FP
  #ifdef CONFIG_ALTIVEC
@@@ -1931,42 -2229,18 +2232,18 @@@ END_FTR_SECTION_IFSET(CPU_FTR_VSX
  #endif
        mtmsrd  r8
        isync
-       lfd     fr0,VCPU_FPSCR(r4)
-       MTFSF_L(fr0)
- #ifdef CONFIG_VSX
- BEGIN_FTR_SECTION
-       reg = 0
-       .rept   32
-       li      r7,reg*16+VCPU_VSRS
-       LXVD2X(reg,R7,R4)
-       reg = reg + 1
-       .endr
- FTR_SECTION_ELSE
- #endif
-       reg = 0
-       .rept   32
-       lfd     reg,reg*8+VCPU_FPRS(r4)
-       reg = reg + 1
-       .endr
- #ifdef CONFIG_VSX
- ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
- #endif
+       addi    r3,r4,VCPU_FPRS
+       bl      .load_fp_state
  #ifdef CONFIG_ALTIVEC
  BEGIN_FTR_SECTION
-       li      r7,VCPU_VSCR
-       lvx     vr0,r7,r4
-       mtvscr  vr0
-       reg = 0
-       .rept   32
-       li      r7,reg*16+VCPU_VRS
-       lvx     reg,r7,r4
-       reg = reg + 1
-       .endr
+       addi    r3,r31,VCPU_VRS
+       bl      .load_vr_state
  END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  #endif
        lwz     r7,VCPU_VRSAVE(r4)
        mtspr   SPRN_VRSAVE,r7
+       mtlr    r30
+       mr      r4,r31
        blr
  
  /*
index 5b9e9063cfaf0c407be267a67ab26d35fcc84a93,6a5fc7d53de67248a5b9d79aa0385a0182cf6c63..c5c052a9729c95d14591087fe71b20168237dc5d
@@@ -41,6 -41,7 +41,7 @@@
  #include <linux/vmalloc.h>
  #include <linux/highmem.h>
  #include <linux/module.h>
+ #include <linux/miscdevice.h>
  
  #include "book3s.h"
  
@@@ -66,7 -67,6 +67,7 @@@ static void kvmppc_core_vcpu_load_pr(st
        struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu);
        memcpy(svcpu->slb, to_book3s(vcpu)->slb_shadow, sizeof(svcpu->slb));
        svcpu->slb_max = to_book3s(vcpu)->slb_shadow_max;
 +      svcpu->in_use = 0;
        svcpu_put(svcpu);
  #endif
        vcpu->cpu = smp_processor_id();
@@@ -79,9 -79,6 +80,9 @@@ static void kvmppc_core_vcpu_put_pr(str
  {
  #ifdef CONFIG_PPC_BOOK3S_64
        struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu);
 +      if (svcpu->in_use) {
 +              kvmppc_copy_from_svcpu(vcpu, svcpu);
 +      }
        memcpy(to_book3s(vcpu)->slb_shadow, svcpu->slb, sizeof(svcpu->slb));
        to_book3s(vcpu)->slb_shadow_max = svcpu->slb_max;
        svcpu_put(svcpu);
@@@ -114,26 -111,12 +115,26 @@@ void kvmppc_copy_to_svcpu(struct kvmppc
        svcpu->ctr = vcpu->arch.ctr;
        svcpu->lr  = vcpu->arch.lr;
        svcpu->pc  = vcpu->arch.pc;
 +      svcpu->in_use = true;
  }
  
  /* Copy data touched by real-mode code from shadow vcpu back to vcpu */
  void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
                            struct kvmppc_book3s_shadow_vcpu *svcpu)
  {
 +      /*
 +       * vcpu_put would just call us again because in_use hasn't
 +       * been updated yet.
 +       */
 +      preempt_disable();
 +
 +      /*
 +       * Maybe we were already preempted and synced the svcpu from
 +       * our preempt notifiers. Don't bother touching this svcpu then.
 +       */
 +      if (!svcpu->in_use)
 +              goto out;
 +
        vcpu->arch.gpr[0] = svcpu->gpr[0];
        vcpu->arch.gpr[1] = svcpu->gpr[1];
        vcpu->arch.gpr[2] = svcpu->gpr[2];
        vcpu->arch.fault_dar   = svcpu->fault_dar;
        vcpu->arch.fault_dsisr = svcpu->fault_dsisr;
        vcpu->arch.last_inst   = svcpu->last_inst;
 +      svcpu->in_use = false;
 +
 +out:
 +      preempt_enable();
  }
  
  static int kvmppc_core_check_requests_pr(struct kvm_vcpu *vcpu)
@@@ -566,12 -545,6 +567,6 @@@ static inline int get_fpr_index(int i
  void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
  {
        struct thread_struct *t = &current->thread;
-       u64 *vcpu_fpr = vcpu->arch.fpr;
- #ifdef CONFIG_VSX
-       u64 *vcpu_vsx = vcpu->arch.vsr;
- #endif
-       u64 *thread_fpr = &t->fp_state.fpr[0][0];
-       int i;
  
        /*
         * VSX instructions can access FP and vector registers, so if
                 * both the traditional FP registers and the added VSX
                 * registers into thread.fp_state.fpr[].
                 */
-               if (current->thread.regs->msr & MSR_FP)
+               if (t->regs->msr & 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->fp_state.fpscr;
- #ifdef CONFIG_VSX
-               if (cpu_has_feature(CPU_FTR_VSX))
-                       for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr) / 2; i++)
-                               vcpu_vsx[i] = thread_fpr[get_fpr_index(i) + 1];
- #endif
+               t->fp_save_area = NULL;
        }
  
  #ifdef CONFIG_ALTIVEC
        if (msr & MSR_VEC) {
                if (current->thread.regs->msr & MSR_VEC)
                        giveup_altivec(current);
-               memcpy(vcpu->arch.vr, t->vr_state.vr, sizeof(vcpu->arch.vr));
-               vcpu->arch.vscr = t->vr_state.vscr;
+               t->vr_save_area = NULL;
        }
  #endif
  
@@@ -661,12 -624,6 +646,6 @@@ static int kvmppc_handle_ext(struct kvm
                             ulong msr)
  {
        struct thread_struct *t = &current->thread;
-       u64 *vcpu_fpr = vcpu->arch.fpr;
- #ifdef CONFIG_VSX
-       u64 *vcpu_vsx = vcpu->arch.vsr;
- #endif
-       u64 *thread_fpr = &t->fp_state.fpr[0][0];
-       int i;
  
        /* When we have paired singles, we emulate in software */
        if (vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)
  #endif
  
        if (msr & MSR_FP) {
-               for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
-                       thread_fpr[get_fpr_index(i)] = vcpu_fpr[i];
- #ifdef CONFIG_VSX
-               for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr) / 2; i++)
-                       thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i];
- #endif
-               t->fp_state.fpscr = vcpu->arch.fpscr;
-               t->fpexc_mode = 0;
-               kvmppc_load_up_fpu();
+               enable_kernel_fp();
+               load_fp_state(&vcpu->arch.fp);
+               t->fp_save_area = &vcpu->arch.fp;
        }
  
        if (msr & MSR_VEC) {
  #ifdef CONFIG_ALTIVEC
-               memcpy(t->vr_state.vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
-               t->vr_state.vscr = vcpu->arch.vscr;
-               t->vrsave = -1;
-               kvmppc_load_up_altivec();
+               enable_kernel_altivec();
+               load_vr_state(&vcpu->arch.vr);
+               t->vr_save_area = &vcpu->arch.vr;
  #endif
        }
  
-       current->thread.regs->msr |= msr;
+       t->regs->msr |= msr;
        vcpu->arch.guest_owned_ext |= msr;
        kvmppc_recalc_shadow_msr(vcpu);
  
@@@ -743,11 -693,15 +715,15 @@@ static void kvmppc_handle_lost_ext(stru
        if (!lost_ext)
                return;
  
-       if (lost_ext & MSR_FP)
-               kvmppc_load_up_fpu();
+       if (lost_ext & MSR_FP) {
+               enable_kernel_fp();
+               load_fp_state(&vcpu->arch.fp);
+       }
  #ifdef CONFIG_ALTIVEC
-       if (lost_ext & MSR_VEC)
-               kvmppc_load_up_altivec();
+       if (lost_ext & MSR_VEC) {
+               enable_kernel_altivec();
+               load_vr_state(&vcpu->arch.vr);
+       }
  #endif
        current->thread.regs->msr |= lost_ext;
  }
@@@ -873,6 -827,7 +849,7 @@@ int kvmppc_handle_exit_pr(struct kvm_ru
        /* We're good on these - the host merely wanted to get our attention */
        case BOOK3S_INTERRUPT_DECREMENTER:
        case BOOK3S_INTERRUPT_HV_DECREMENTER:
+       case BOOK3S_INTERRUPT_DOORBELL:
                vcpu->stat.dec_exits++;
                r = RESUME_GUEST;
                break;
@@@ -1045,14 -1000,14 +1022,14 @@@ program_interrupt
                 * and if we really did time things so badly, then we just exit
                 * again due to a host external interrupt.
                 */
-               local_irq_disable();
                s = kvmppc_prepare_to_enter(vcpu);
-               if (s <= 0) {
-                       local_irq_enable();
+               if (s <= 0)
                        r = s;
-               } else {
+               else {
+                       /* interrupts now hard-disabled */
                        kvmppc_fix_ee_before_entry();
                }
                kvmppc_handle_lost_ext(vcpu);
        }
  
@@@ -1133,19 -1088,6 +1110,6 @@@ static int kvmppc_get_one_reg_pr(struc
        case KVM_REG_PPC_HIOR:
                *val = get_reg_val(id, to_book3s(vcpu)->hior);
                break;
- #ifdef CONFIG_VSX
-       case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: {
-               long int i = id - KVM_REG_PPC_VSR0;
-               if (!cpu_has_feature(CPU_FTR_VSX)) {
-                       r = -ENXIO;
-                       break;
-               }
-               val->vsxval[0] = vcpu->arch.fpr[i];
-               val->vsxval[1] = vcpu->arch.vsr[i];
-               break;
-       }
- #endif /* CONFIG_VSX */
        default:
                r = -EINVAL;
                break;
@@@ -1164,19 -1106,6 +1128,6 @@@ static int kvmppc_set_one_reg_pr(struc
                to_book3s(vcpu)->hior = set_reg_val(id, *val);
                to_book3s(vcpu)->hior_explicit = true;
                break;
- #ifdef CONFIG_VSX
-       case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: {
-               long int i = id - KVM_REG_PPC_VSR0;
-               if (!cpu_has_feature(CPU_FTR_VSX)) {
-                       r = -ENXIO;
-                       break;
-               }
-               vcpu->arch.fpr[i] = val->vsxval[0];
-               vcpu->arch.vsr[i] = val->vsxval[1];
-               break;
-       }
- #endif /* CONFIG_VSX */
        default:
                r = -EINVAL;
                break;
@@@ -1274,17 -1203,9 +1225,9 @@@ static void kvmppc_core_vcpu_free_pr(st
  static int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
  {
        int ret;
-       struct thread_fp_state fp;
-       int fpexc_mode;
  #ifdef CONFIG_ALTIVEC
-       struct thread_vr_state vr;
        unsigned long uninitialized_var(vrsave);
-       int used_vr;
  #endif
- #ifdef CONFIG_VSX
-       int used_vsr;
- #endif
-       ulong ext_msr;
  
        /* Check if we can run the vcpu at all */
        if (!vcpu->arch.sane) {
         * really did time things so badly, then we just exit again due to
         * a host external interrupt.
         */
-       local_irq_disable();
        ret = kvmppc_prepare_to_enter(vcpu);
-       if (ret <= 0) {
-               local_irq_enable();
+       if (ret <= 0)
                goto out;
-       }
+       /* interrupts now hard-disabled */
  
-       /* Save FPU state in stack */
+       /* Save FPU state in thread_struct */
        if (current->thread.regs->msr & MSR_FP)
                giveup_fpu(current);
-       fp = current->thread.fp_state;
-       fpexc_mode = current->thread.fpexc_mode;
  
  #ifdef CONFIG_ALTIVEC
-       /* Save Altivec state in stack */
-       used_vr = current->thread.used_vr;
-       if (used_vr) {
-               if (current->thread.regs->msr & MSR_VEC)
-                       giveup_altivec(current);
-               vr = current->thread.vr_state;
-               vrsave = current->thread.vrsave;
-       }
+       /* Save Altivec state in thread_struct */
+       if (current->thread.regs->msr & MSR_VEC)
+               giveup_altivec(current);
  #endif
  
  #ifdef CONFIG_VSX
-       /* Save VSX state in stack */
-       used_vsr = current->thread.used_vsr;
-       if (used_vsr && (current->thread.regs->msr & MSR_VSX))
+       /* Save VSX state in thread_struct */
+       if (current->thread.regs->msr & MSR_VSX)
                __giveup_vsx(current);
  #endif
  
-       /* Remember the MSR with disabled extensions */
-       ext_msr = current->thread.regs->msr;
        /* Preload FPU if it's enabled */
        if (vcpu->arch.shared->msr & MSR_FP)
                kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP);
        /* Make sure we save the guest FPU/Altivec/VSX state */
        kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX);
  
-       current->thread.regs->msr = ext_msr;
-       /* Restore FPU/VSX state from stack */
-       current->thread.fp_state = fp;
-       current->thread.fpexc_mode = fpexc_mode;
- #ifdef CONFIG_ALTIVEC
-       /* Restore Altivec state from stack */
-       if (used_vr && current->thread.used_vr) {
-               current->thread.vr_state = vr;
-               current->thread.vrsave = vrsave;
-       }
-       current->thread.used_vr = used_vr;
- #endif
- #ifdef CONFIG_VSX
-       current->thread.used_vsr = used_vsr;
- #endif
  out:
        vcpu->mode = OUTSIDE_GUEST_MODE;
        return ret;
@@@ -1606,4 -1495,6 +1517,6 @@@ module_init(kvmppc_book3s_init_pr)
  module_exit(kvmppc_book3s_exit_pr);
  
  MODULE_LICENSE("GPL");
+ MODULE_ALIAS_MISCDEV(KVM_MINOR);
+ MODULE_ALIAS("devname:kvm");
  #endif
index c3c5231adade6f3871709a318fed1abc752040fe,c78ffbc371a566aea92dd2d4aa172c70faba1101..9eec675220e621e029eac8ecf2a5dabfff17df5a
@@@ -153,60 -153,17 +153,13 @@@ _GLOBAL(kvmppc_entry_trampoline
  
        li      r6, MSR_IR | MSR_DR
        andc    r6, r5, r6      /* Clear DR and IR in MSR value */
 -#ifdef CONFIG_PPC_BOOK3S_32
        /*
         * Set EE in HOST_MSR so that it's enabled when we get into our
 -       * C exit handler function.  On 64-bit we delay enabling
 -       * interrupts until we have finished transferring stuff
 -       * to or from the PACA.
 +       * C exit handler function.
         */
        ori     r5, r5, MSR_EE
 -#endif
        mtsrr0  r7
        mtsrr1  r6
        RFI
  
- #if defined(CONFIG_PPC_BOOK3S_32)
- #define STACK_LR      INT_FRAME_SIZE+4
- /* load_up_xxx have to run with MSR_DR=0 on Book3S_32 */
- #define MSR_EXT_START                                         \
-       PPC_STL r20, _NIP(r1);                                  \
-       mfmsr   r20;                                            \
-       LOAD_REG_IMMEDIATE(r3, MSR_DR|MSR_EE);                  \
-       andc    r3,r20,r3;              /* Disable DR,EE */     \
-       mtmsr   r3;                                             \
-       sync
- #define MSR_EXT_END                                           \
-       mtmsr   r20;                    /* Enable DR,EE */      \
-       sync;                                                   \
-       PPC_LL  r20, _NIP(r1)
- #elif defined(CONFIG_PPC_BOOK3S_64)
- #define STACK_LR      _LINK
- #define MSR_EXT_START
- #define MSR_EXT_END
- #endif
- /*
-  * Activate current's external feature (FPU/Altivec/VSX)
-  */
- #define define_load_up(what)                                  \
-                                                               \
- _GLOBAL(kvmppc_load_up_ ## what);                             \
-       PPC_STLU r1, -INT_FRAME_SIZE(r1);                       \
-       mflr    r3;                                             \
-       PPC_STL r3, STACK_LR(r1);                               \
-       MSR_EXT_START;                                          \
-                                                               \
-       bl      FUNC(load_up_ ## what);                         \
-                                                               \
-       MSR_EXT_END;                                            \
-       PPC_LL  r3, STACK_LR(r1);                               \
-       mtlr    r3;                                             \
-       addi    r1, r1, INT_FRAME_SIZE;                         \
-       blr
- define_load_up(fpu)
- #ifdef CONFIG_ALTIVEC
- define_load_up(altivec)
- #endif
  #include "book3s_segment.S"
diff --combined arch/powerpc/kvm/booke.c
index 0591e05db74b1a1a1f906af6a2a67cf9770320fa,07b89c711898974423d2e02a3a40fcb948d6e681..ab62109fdfa3f71a43701c7d08220db2cb826066
@@@ -643,7 -643,7 +643,7 @@@ int kvmppc_core_prepare_to_enter(struc
                local_irq_enable();
                kvm_vcpu_block(vcpu);
                clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
-               local_irq_disable();
+               hard_irq_disable();
  
                kvmppc_set_exit_type(vcpu, EMULATED_MTMSRWE_EXITS);
                r = 1;
@@@ -681,35 -681,23 +681,23 @@@ int kvmppc_core_check_requests(struct k
  int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
  {
        int ret, s;
 -      struct thread_struct thread;
 +      struct debug_reg debug;
- #ifdef CONFIG_PPC_FPU
-       struct thread_fp_state fp;
-       int fpexc_mode;
- #endif
  
        if (!vcpu->arch.sane) {
                kvm_run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
                return -EINVAL;
        }
  
-       local_irq_disable();
        s = kvmppc_prepare_to_enter(vcpu);
        if (s <= 0) {
-               local_irq_enable();
                ret = s;
                goto out;
        }
+       /* interrupts now hard-disabled */
  
  #ifdef CONFIG_PPC_FPU
        /* Save userspace FPU state in stack */
        enable_kernel_fp();
-       fp = current->thread.fp_state;
-       fpexc_mode = current->thread.fpexc_mode;
-       /* Restore guest FPU state to thread */
-       memcpy(current->thread.fp_state.fpr, vcpu->arch.fpr,
-              sizeof(vcpu->arch.fpr));
-       current->thread.fp_state.fpscr = vcpu->arch.fpscr;
  
        /*
         * Since we can't trap on MSR_FP in GS-mode, we consider the guest
  #endif
  
        /* Switch to guest debug context */
 -      thread.debug = vcpu->arch.shadow_dbg_reg;
 -      switch_booke_debug_regs(&thread);
 -      thread.debug = current->thread.debug;
 +      debug = vcpu->arch.shadow_dbg_reg;
 +      switch_booke_debug_regs(&debug);
 +      debug = current->thread.debug;
        current->thread.debug = vcpu->arch.shadow_dbg_reg;
  
+       vcpu->arch.pgdir = current->mm->pgd;
        kvmppc_fix_ee_before_entry();
  
        ret = __kvmppc_vcpu_run(kvm_run, vcpu);
           We also get here with interrupts enabled. */
  
        /* Switch back to user space debug context */
 -      switch_booke_debug_regs(&thread);
 -      current->thread.debug = thread.debug;
 +      switch_booke_debug_regs(&debug);
 +      current->thread.debug = debug;
  
  #ifdef CONFIG_PPC_FPU
        kvmppc_save_guest_fp(vcpu);
  
        vcpu->fpu_active = 0;
-       /* Save guest FPU state from thread */
-       memcpy(vcpu->arch.fpr, current->thread.fp_state.fpr,
-              sizeof(vcpu->arch.fpr));
-       vcpu->arch.fpscr = current->thread.fp_state.fpscr;
-       /* Restore userspace FPU state from stack */
-       current->thread.fp_state = fp;
-       current->thread.fpexc_mode = fpexc_mode;
  #endif
  
  out:
@@@ -898,17 -878,6 +878,6 @@@ int kvmppc_handle_exit(struct kvm_run *
        int s;
        int idx;
  
- #ifdef CONFIG_PPC64
-       WARN_ON(local_paca->irq_happened != 0);
- #endif
-       /*
-        * We enter with interrupts disabled in hardware, but
-        * we need to call hard_irq_disable anyway to ensure that
-        * the software state is kept in sync.
-        */
-       hard_irq_disable();
        /* update before a new last_exit_type is rewritten */
        kvmppc_update_timing_stats(vcpu);
  
         * aren't already exiting to userspace for some other reason.
         */
        if (!(r & RESUME_HOST)) {
-               local_irq_disable();
                s = kvmppc_prepare_to_enter(vcpu);
-               if (s <= 0) {
-                       local_irq_enable();
+               if (s <= 0)
                        r = (s << 2) | RESUME_HOST | (r & RESUME_FLAG_NV);
-               } else {
+               else {
+                       /* interrupts now hard-disabled */
                        kvmppc_fix_ee_before_entry();
                }
        }