return (r == RESUME_GUEST || r == RESUME_GUEST_NV);
 }
 
+static inline bool is_kvmppc_hv_enabled(struct kvm *kvm);
+static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu)
+{
+       /* Only PR KVM supports the magic page */
+       return !is_kvmppc_hv_enabled(vcpu->kvm);
+}
+
 /* Magic register values loaded into r3 and r4 before the 'sc' assembly
  * instruction for the OSI hypercalls */
 #define OSI_SC_MAGIC_R3                        0x113724FA
 
 int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
              bool data)
 {
+       ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK;
        struct kvmppc_pte pte;
        int r;
 
        if (!pte.may_write)
                return -EPERM;
 
+       /* Magic page override */
+       if (kvmppc_supports_magic_page(vcpu) && mp_pa &&
+           ((pte.raddr & KVM_PAM & PAGE_MASK) == mp_pa) &&
+           !(kvmppc_get_msr(vcpu) & MSR_PR)) {
+               void *magic = vcpu->arch.shared;
+               magic += pte.eaddr & 0xfff;
+               memcpy(magic, ptr, size);
+               return EMULATE_DONE;
+       }
+
        if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size))
                return EMULATE_DO_MMIO;
 
 int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
                      bool data)
 {
+       ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK;
        struct kvmppc_pte pte;
        int rc;
 
        if (!data && !pte.may_execute)
                return -ENOEXEC;
 
+       /* Magic page override */
+       if (kvmppc_supports_magic_page(vcpu) && mp_pa &&
+           ((pte.raddr & KVM_PAM & PAGE_MASK) == mp_pa) &&
+           !(kvmppc_get_msr(vcpu) & MSR_PR)) {
+               void *magic = vcpu->arch.shared;
+               magic += pte.eaddr & 0xfff;
+               memcpy(ptr, magic, size);
+               return EMULATE_DONE;
+       }
+
        if (kvm_read_guest(vcpu->kvm, pte.raddr, ptr, size))
                return EMULATE_DO_MMIO;