Commit 83a05510 authored by Paul Mackerras's avatar Paul Mackerras Committed by Michael Ellerman

KVM: PPC: Book3S HV: Add nested shadow page tables to debugfs

This adds a list of valid shadow PTEs for each nested guest to
the 'radix' file for the guest in debugfs.  This can be useful for
debugging.
Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent de760db4
...@@ -120,6 +120,7 @@ struct rmap_nested { ...@@ -120,6 +120,7 @@ struct rmap_nested {
struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid, struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
bool create); bool create);
void kvmhv_put_nested(struct kvm_nested_guest *gp); void kvmhv_put_nested(struct kvm_nested_guest *gp);
int kvmhv_nested_next_lpid(struct kvm *kvm, int lpid);
/* Encoding of first parameter for H_TLB_INVALIDATE */ /* Encoding of first parameter for H_TLB_INVALIDATE */
#define H_TLBIE_P1_ENC(ric, prs, r) (___PPC_RIC(ric) | ___PPC_PRS(prs) | \ #define H_TLBIE_P1_ENC(ric, prs, r) (___PPC_RIC(ric) | ___PPC_PRS(prs) | \
......
...@@ -1002,6 +1002,7 @@ struct debugfs_radix_state { ...@@ -1002,6 +1002,7 @@ struct debugfs_radix_state {
struct kvm *kvm; struct kvm *kvm;
struct mutex mutex; struct mutex mutex;
unsigned long gpa; unsigned long gpa;
int lpid;
int chars_left; int chars_left;
int buf_index; int buf_index;
char buf[128]; char buf[128];
...@@ -1043,6 +1044,7 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, ...@@ -1043,6 +1044,7 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf,
struct kvm *kvm; struct kvm *kvm;
unsigned long gpa; unsigned long gpa;
pgd_t *pgt; pgd_t *pgt;
struct kvm_nested_guest *nested;
pgd_t pgd, *pgdp; pgd_t pgd, *pgdp;
pud_t pud, *pudp; pud_t pud, *pudp;
pmd_t pmd, *pmdp; pmd_t pmd, *pmdp;
...@@ -1077,10 +1079,39 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, ...@@ -1077,10 +1079,39 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf,
} }
gpa = p->gpa; gpa = p->gpa;
pgt = kvm->arch.pgtable; nested = NULL;
while (len != 0 && gpa < RADIX_PGTABLE_RANGE) { pgt = NULL;
while (len != 0 && p->lpid >= 0) {
if (gpa >= RADIX_PGTABLE_RANGE) {
gpa = 0;
pgt = NULL;
if (nested) {
kvmhv_put_nested(nested);
nested = NULL;
}
p->lpid = kvmhv_nested_next_lpid(kvm, p->lpid);
p->hdr = 0;
if (p->lpid < 0)
break;
}
if (!pgt) {
if (p->lpid == 0) {
pgt = kvm->arch.pgtable;
} else {
nested = kvmhv_get_nested(kvm, p->lpid, false);
if (!nested) {
gpa = RADIX_PGTABLE_RANGE;
continue;
}
pgt = nested->shadow_pgtable;
}
}
n = 0;
if (!p->hdr) { if (!p->hdr) {
n = scnprintf(p->buf, sizeof(p->buf), if (p->lpid > 0)
n = scnprintf(p->buf, sizeof(p->buf),
"\nNested LPID %d: ", p->lpid);
n += scnprintf(p->buf + n, sizeof(p->buf) - n,
"pgdir: %lx\n", (unsigned long)pgt); "pgdir: %lx\n", (unsigned long)pgt);
p->hdr = 1; p->hdr = 1;
goto copy; goto copy;
...@@ -1146,6 +1177,8 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, ...@@ -1146,6 +1177,8 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf,
} }
} }
p->gpa = gpa; p->gpa = gpa;
if (nested)
kvmhv_put_nested(nested);
out: out:
mutex_unlock(&p->mutex); mutex_unlock(&p->mutex);
......
...@@ -1274,3 +1274,18 @@ long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu) ...@@ -1274,3 +1274,18 @@ long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu)
mutex_unlock(&gp->tlb_lock); mutex_unlock(&gp->tlb_lock);
return ret; return ret;
} }
int kvmhv_nested_next_lpid(struct kvm *kvm, int lpid)
{
int ret = -1;
spin_lock(&kvm->mmu_lock);
while (++lpid <= kvm->arch.max_nested_lpid) {
if (kvm->arch.nested_guests[lpid]) {
ret = lpid;
break;
}
}
spin_unlock(&kvm->mmu_lock);
return ret;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment