|
@@ -312,6 +312,7 @@ EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio);
|
|
|
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;
|
|
|
|
|
@@ -327,6 +328,16 @@ int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
|
|
|
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;
|
|
|
|
|
@@ -337,6 +348,7 @@ EXPORT_SYMBOL_GPL(kvmppc_st);
|
|
|
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;
|
|
|
|
|
@@ -355,6 +367,16 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
|
|
|
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;
|
|
|
|