提交 c12fb43c 编写于 作者: A Alexander Graf

KVM: PPC: Handle magic page in kvmppc_ld/st

We use kvmppc_ld and kvmppc_st to emulate load/store instructions that may as
well access the magic page. Special case it out so that we can properly access
it.
Signed-off-by: NAlexander Graf <agraf@suse.de>
上级 c45c5514
...@@ -286,6 +286,13 @@ static inline bool is_kvmppc_resume_guest(int r) ...@@ -286,6 +286,13 @@ static inline bool is_kvmppc_resume_guest(int r)
return (r == RESUME_GUEST || r == RESUME_GUEST_NV); 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 /* Magic register values loaded into r3 and r4 before the 'sc' assembly
* instruction for the OSI hypercalls */ * instruction for the OSI hypercalls */
#define OSI_SC_MAGIC_R3 0x113724FA #define OSI_SC_MAGIC_R3 0x113724FA
......
...@@ -103,4 +103,14 @@ static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) ...@@ -103,4 +103,14 @@ static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu)
{ {
return vcpu->arch.fault_dear; return vcpu->arch.fault_dear;
} }
static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu)
{
/* Magic page is only supported on e500v2 */
#ifdef CONFIG_KVM_E500V2
return true;
#else
return false;
#endif
}
#endif /* __ASM_KVM_BOOKE_H__ */ #endif /* __ASM_KVM_BOOKE_H__ */
...@@ -312,6 +312,7 @@ EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio); ...@@ -312,6 +312,7 @@ EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio);
int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
bool data) bool data)
{ {
ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK;
struct kvmppc_pte pte; struct kvmppc_pte pte;
int r; int r;
...@@ -327,6 +328,16 @@ int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, ...@@ -327,6 +328,16 @@ int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
if (!pte.may_write) if (!pte.may_write)
return -EPERM; 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)) if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size))
return EMULATE_DO_MMIO; return EMULATE_DO_MMIO;
...@@ -337,6 +348,7 @@ EXPORT_SYMBOL_GPL(kvmppc_st); ...@@ -337,6 +348,7 @@ EXPORT_SYMBOL_GPL(kvmppc_st);
int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
bool data) bool data)
{ {
ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK;
struct kvmppc_pte pte; struct kvmppc_pte pte;
int rc; int rc;
...@@ -355,6 +367,16 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, ...@@ -355,6 +367,16 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
if (!data && !pte.may_execute) if (!data && !pte.may_execute)
return -ENOEXEC; 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)) if (kvm_read_guest(vcpu->kvm, pte.raddr, ptr, size))
return EMULATE_DO_MMIO; return EMULATE_DO_MMIO;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册