map this shared page using the KVM hypercall KVM_HC_PPC_MAP_MAGIC_PAGE.
 
 With this hypercall issued the guest always gets the magic page mapped at the
-desired location in effective and physical address space. For now, we always
-map the page to -4096. This way we can access it using absolute load and store
-functions. The following instruction reads the first field of the magic page:
+desired location. The first parameter indicates the effective address when the
+MMU is enabled. The second parameter indicates the address in real mode, if
+applicable to the target. For now, we always map the page to -4096. This way we
+can access it using absolute load and store functions. The following
+instruction reads the first field of the magic page:
 
        ld      rX, -4096(0)
 
 
 
 extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu);
 extern int kvmppc_kvm_pv(struct kvm_vcpu *vcpu);
+extern void kvmppc_map_magic(struct kvm_vcpu *vcpu);
 
 /*
  * Cuts out inst bits with ordering according to spec.
 
                gpa_t gpaddr;
                gfn_t gfn;
 
+#ifdef CONFIG_KVM_E500
+               if (!(vcpu->arch.shared->msr & MSR_PR) &&
+                   (eaddr & PAGE_MASK) == vcpu->arch.magic_page_ea) {
+                       kvmppc_map_magic(vcpu);
+                       kvmppc_account_exit(vcpu, DTLB_VIRT_MISS_EXITS);
+                       r = RESUME_GUEST;
+
+                       break;
+               }
+#endif
+
                /* Check the guest TLB. */
                gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr);
                if (gtlb_index < 0) {
 
 
 static inline unsigned int tlb1_max_shadow_size(void)
 {
-       return tlb1_entry_num - tlbcam_index;
+       /* reserve one entry for magic page */
+       return tlb1_entry_num - tlbcam_index - 1;
 }
 
 static inline int tlbe_is_writable(struct tlbe *tlbe)
        }
 }
 
+void kvmppc_map_magic(struct kvm_vcpu *vcpu)
+{
+       struct tlbe magic;
+       ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK;
+       pfn_t pfn;
+
+       pfn = (pfn_t)virt_to_phys((void *)shared_page) >> PAGE_SHIFT;
+       get_page(pfn_to_page(pfn));
+
+       magic.mas1 = MAS1_VALID | MAS1_TS |
+                    MAS1_TSIZE(BOOK3E_PAGESZ_4K);
+       magic.mas2 = vcpu->arch.magic_page_ea | MAS2_M;
+       magic.mas3 = (pfn << PAGE_SHIFT) |
+                    MAS3_SW | MAS3_SR | MAS3_UW | MAS3_UR;
+       magic.mas7 = pfn >> (32 - PAGE_SHIFT);
+
+       __write_host_tlbe(&magic, MAS0_TLBSEL(1) | MAS0_ESEL(tlbcam_index));
+}
+
 void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu)
 {
 }
 
        }
        case HC_VENDOR_KVM | KVM_HC_FEATURES:
                r = HC_EV_SUCCESS;
-#if defined(CONFIG_PPC_BOOK3S) /* XXX Missing magic page on BookE */
+#if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500)
+               /* XXX Missing magic page on 44x */
                r2 |= (1 << KVM_FEATURE_MAGIC_PAGE);
 #endif