KVM: PPC: Move kvmppc_ld/st to common code
We have enough common infrastructure now to resolve GVA->GPA mappings at runtime. With this we can move our book3s specific helpers to load / store in guest virtual address space to common code as well. Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
7d15c06f1a
commit
35c4a7330d
@ -148,8 +148,8 @@ extern void kvmppc_mmu_hpte_sysexit(void);
|
||||
extern int kvmppc_mmu_hv_init(void);
|
||||
extern int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hc);
|
||||
|
||||
/* XXX remove this export when load_last_inst() is generic */
|
||||
extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data);
|
||||
extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data);
|
||||
extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec);
|
||||
extern void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
|
||||
unsigned int vec);
|
||||
|
@ -111,15 +111,15 @@ struct kvm_vcpu_stat {
|
||||
u32 halt_wakeup;
|
||||
u32 dbell_exits;
|
||||
u32 gdbell_exits;
|
||||
u32 ld;
|
||||
u32 st;
|
||||
#ifdef CONFIG_PPC_BOOK3S
|
||||
u32 pf_storage;
|
||||
u32 pf_instruc;
|
||||
u32 sp_storage;
|
||||
u32 sp_instruc;
|
||||
u32 queue_intr;
|
||||
u32 ld;
|
||||
u32 ld_slow;
|
||||
u32 st;
|
||||
u32 st_slow;
|
||||
#endif
|
||||
};
|
||||
|
@ -80,6 +80,10 @@ extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
extern int kvmppc_load_last_inst(struct kvm_vcpu *vcpu,
|
||||
enum instruction_type type, u32 *inst);
|
||||
|
||||
extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
|
||||
bool data);
|
||||
extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
|
||||
bool data);
|
||||
extern int kvmppc_emulate_instruction(struct kvm_run *run,
|
||||
struct kvm_vcpu *vcpu);
|
||||
extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
|
@ -410,87 +410,6 @@ int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, enum xlate_instdata xlid,
|
||||
return r;
|
||||
}
|
||||
|
||||
static hva_t kvmppc_bad_hva(void)
|
||||
{
|
||||
return PAGE_OFFSET;
|
||||
}
|
||||
|
||||
static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
|
||||
{
|
||||
hva_t hpage;
|
||||
|
||||
hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
|
||||
if (kvm_is_error_hva(hpage))
|
||||
goto err;
|
||||
|
||||
return hpage | (pte->raddr & ~PAGE_MASK);
|
||||
err:
|
||||
return kvmppc_bad_hva();
|
||||
}
|
||||
|
||||
int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
|
||||
bool data)
|
||||
{
|
||||
struct kvmppc_pte pte;
|
||||
int r;
|
||||
|
||||
vcpu->stat.st++;
|
||||
|
||||
r = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST,
|
||||
XLATE_WRITE, &pte);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*eaddr = pte.raddr;
|
||||
|
||||
if (!pte.may_write)
|
||||
return -EPERM;
|
||||
|
||||
if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size))
|
||||
return EMULATE_DO_MMIO;
|
||||
|
||||
return EMULATE_DONE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvmppc_st);
|
||||
|
||||
int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
|
||||
bool data)
|
||||
{
|
||||
struct kvmppc_pte pte;
|
||||
hva_t hva = *eaddr;
|
||||
int rc;
|
||||
|
||||
vcpu->stat.ld++;
|
||||
|
||||
rc = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST,
|
||||
XLATE_READ, &pte);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
*eaddr = pte.raddr;
|
||||
|
||||
if (!pte.may_read)
|
||||
return -EPERM;
|
||||
|
||||
if (!data && !pte.may_execute)
|
||||
return -ENOEXEC;
|
||||
|
||||
hva = kvmppc_pte_to_hva(vcpu, &pte);
|
||||
if (kvm_is_error_hva(hva))
|
||||
goto mmio;
|
||||
|
||||
if (copy_from_user(ptr, (void __user *)hva, size)) {
|
||||
printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva);
|
||||
goto mmio;
|
||||
}
|
||||
|
||||
return EMULATE_DONE;
|
||||
|
||||
mmio:
|
||||
return EMULATE_DO_MMIO;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvmppc_ld);
|
||||
|
||||
int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type,
|
||||
u32 *inst)
|
||||
{
|
||||
|
@ -309,6 +309,87 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio);
|
||||
|
||||
static hva_t kvmppc_bad_hva(void)
|
||||
{
|
||||
return PAGE_OFFSET;
|
||||
}
|
||||
|
||||
static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
|
||||
{
|
||||
hva_t hpage;
|
||||
|
||||
hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
|
||||
if (kvm_is_error_hva(hpage))
|
||||
goto err;
|
||||
|
||||
return hpage | (pte->raddr & ~PAGE_MASK);
|
||||
err:
|
||||
return kvmppc_bad_hva();
|
||||
}
|
||||
|
||||
int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
|
||||
bool data)
|
||||
{
|
||||
struct kvmppc_pte pte;
|
||||
int r;
|
||||
|
||||
vcpu->stat.st++;
|
||||
|
||||
r = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST,
|
||||
XLATE_WRITE, &pte);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*eaddr = pte.raddr;
|
||||
|
||||
if (!pte.may_write)
|
||||
return -EPERM;
|
||||
|
||||
if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size))
|
||||
return EMULATE_DO_MMIO;
|
||||
|
||||
return EMULATE_DONE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvmppc_st);
|
||||
|
||||
int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
|
||||
bool data)
|
||||
{
|
||||
struct kvmppc_pte pte;
|
||||
hva_t hva = *eaddr;
|
||||
int rc;
|
||||
|
||||
vcpu->stat.ld++;
|
||||
|
||||
rc = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST,
|
||||
XLATE_READ, &pte);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
*eaddr = pte.raddr;
|
||||
|
||||
if (!pte.may_read)
|
||||
return -EPERM;
|
||||
|
||||
if (!data && !pte.may_execute)
|
||||
return -ENOEXEC;
|
||||
|
||||
hva = kvmppc_pte_to_hva(vcpu, &pte);
|
||||
if (kvm_is_error_hva(hva))
|
||||
goto mmio;
|
||||
|
||||
if (copy_from_user(ptr, (void __user *)hva, size)) {
|
||||
printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva);
|
||||
goto mmio;
|
||||
}
|
||||
|
||||
return EMULATE_DONE;
|
||||
|
||||
mmio:
|
||||
return EMULATE_DO_MMIO;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvmppc_ld);
|
||||
|
||||
int kvm_arch_hardware_enable(void *garbage)
|
||||
{
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user