Skip to content

Commit

Permalink
KVM: PPC: Book3S: Make kvmppc_ld return a more accurate error indication
Browse files Browse the repository at this point in the history
At present, kvmppc_ld calls kvmppc_xlate, and if kvmppc_xlate returns
any error indication, it returns -ENOENT, which is taken to mean an
HPTE not found error.  However, the error could have been a segment
found (no SLB entry) or a permission error.  Similarly,
kvmppc_pte_to_hva currently does permission checking, but any error
from it is taken by kvmppc_ld to mean that the access is an emulated
MMIO access.  Also, kvmppc_ld does no execute permission checking.

This fixes these problems by (a) returning any error from kvmppc_xlate
directly, (b) moving the permission check from kvmppc_pte_to_hva
into kvmppc_ld, and (c) adding an execute permission check to kvmppc_ld.

This is similar to what was done for kvmppc_st() by commit 82ff911317c3
("KVM: PPC: Deflect page write faults properly in kvmppc_st").

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
  • Loading branch information
Paul Mackerras authored and Alexander Graf committed Jul 28, 2014
1 parent ef1af2e commit 1b2e33b
Showing 1 changed file with 12 additions and 13 deletions.
25 changes: 12 additions & 13 deletions arch/powerpc/kvm/book3s.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,17 +413,10 @@ 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,
bool read)
static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
{
hva_t hpage;

if (read && !pte->may_read)
goto err;

if (!read && !pte->may_write)
goto err;

hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
if (kvm_is_error_hva(hpage))
goto err;
Expand Down Expand Up @@ -462,15 +455,23 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
{
struct kvmppc_pte pte;
hva_t hva = *eaddr;
int rc;

vcpu->stat.ld++;

if (kvmppc_xlate(vcpu, *eaddr, data, false, &pte))
goto nopte;
rc = kvmppc_xlate(vcpu, *eaddr, data, false, &pte);
if (rc)
return rc;

*eaddr = pte.raddr;

hva = kvmppc_pte_to_hva(vcpu, &pte, true);
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;

Expand All @@ -481,8 +482,6 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,

return EMULATE_DONE;

nopte:
return -ENOENT;
mmio:
return EMULATE_DO_MMIO;
}
Expand Down

0 comments on commit 1b2e33b

Please sign in to comment.