extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
                                   gva_t eend, u32 asid);
 extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
+extern void kvmppc_mmu_switch_pid(struct kvm_vcpu *vcpu, u32 pid);
 
 /* XXX Book E specific */
 extern void kvmppc_tlbe_set_modified(struct kvm_vcpu *vcpu, unsigned int i);
                kvm_vcpu_block(vcpu);
 }
 
+static inline void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid)
+{
+       if (vcpu->arch.pid != new_pid) {
+               vcpu->arch.pid = new_pid;
+               vcpu->arch.swap_pid = 1;
+       }
+}
+
 #endif /* __POWERPC_KVM_PPC_H__ */
 
        DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5));
        DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
        DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7));
-       DEFINE(VCPU_PID, offsetof(struct kvm_vcpu, arch.pid));
+       DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid));
 
        DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
        DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
 
 
        /* XXX what about AS? */
 
-       stlbe->tid = asid & 0xff;
+       stlbe->tid = !(asid & 0xff);
 
        /* Force TS=1 for all guest mappings. */
        /* For now we hardcode 4KB mappings, but it will be important to
 void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
                            gva_t eend, u32 asid)
 {
-       unsigned int pid = asid & 0xff;
+       unsigned int pid = !(asid & 0xff);
        int i;
 
        /* XXX Replace loop with fancy data structures. */
        up_write(¤t->mm->mmap_sem);
 }
 
-/* Invalidate all mappings, so that when they fault back in they will get the
- * proper permission bits. */
+/* Invalidate all mappings on the privilege switch after PID has been changed.
+ * The guest always runs with PID=1, so we must clear the entire TLB when
+ * switching address spaces. */
 void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode)
 {
        int i;
 
-       /* XXX Replace loop with fancy data structures. */
-       down_write(¤t->mm->mmap_sem);
-       for (i = 0; i <= tlb_44x_hwater; i++) {
-               struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i];
-
-               kvmppc_44x_shadow_release(vcpu, i);
-               stlbe->word0 = 0;
-               kvmppc_tlbe_set_modified(vcpu, i);
-               KVMTRACE_5D(STLB_INVAL, vcpu, i,
-                               stlbe->tid, stlbe->word0, stlbe->word1,
-                               stlbe->word2, handler);
+       if (vcpu->arch.swap_pid) {
+               /* XXX Replace loop with fancy data structures. */
+               down_write(¤t->mm->mmap_sem);
+               for (i = 0; i <= tlb_44x_hwater; i++) {
+                       struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i];
+
+                       /* Future optimization: clear only userspace mappings. */
+                       kvmppc_44x_shadow_release(vcpu, i);
+                       stlbe->word0 = 0;
+                       kvmppc_tlbe_set_modified(vcpu, i);
+                       KVMTRACE_5D(STLB_INVAL, vcpu, i,
+                                   stlbe->tid, stlbe->word0, stlbe->word1,
+                                   stlbe->word2, handler);
+               }
+               up_write(¤t->mm->mmap_sem);
+               vcpu->arch.swap_pid = 0;
        }
-       up_write(¤t->mm->mmap_sem);
+
+       vcpu->arch.shadow_pid = !usermode;
 }