Message ID | 1537524123-9578-33-git-send-email-paulus@ozlabs.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: PPC: Book3S HV: Nested HV virtualization | expand |
On Fri, Sep 21, 2018 at 08:02:03PM +1000, Paul Mackerras wrote: > 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. > > Signed-off-by: Paul Mackerras <paulus@ozlabs.org> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> > --- > arch/powerpc/include/asm/kvm_book3s_64.h | 1 + > arch/powerpc/kvm/book3s_64_mmu_radix.c | 39 +++++++++++++++++++++++++++++--- > arch/powerpc/kvm/book3s_hv_nested.c | 15 ++++++++++++ > 3 files changed, 52 insertions(+), 3 deletions(-) > > diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h > index 84c4c0e..12007f6 100644 > --- a/arch/powerpc/include/asm/kvm_book3s_64.h > +++ b/arch/powerpc/include/asm/kvm_book3s_64.h > @@ -50,6 +50,7 @@ struct rmap_nested { > struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int lpid, > bool create); > void kvmhv_put_nested(struct kvm_nested_guest *gp); > +int kvmhv_nested_next_lpid(struct kvm *kvm, int lpid); > > /* Power architecture requires HPT is at least 256kiB, at most 64TiB */ > #define PPC_MIN_HPT_ORDER 18 > diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c > index 52b2a57..41beb9b 100644 > --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c > +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c > @@ -978,6 +978,7 @@ struct debugfs_radix_state { > struct kvm *kvm; > struct mutex mutex; > unsigned long gpa; > + int lpid; > int chars_left; > int buf_index; > char buf[128]; > @@ -1019,6 +1020,7 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, > struct kvm *kvm; > unsigned long gpa; > pgd_t *pgt; > + struct kvm_nested_guest *nested; > pgd_t pgd, *pgdp; > pud_t pud, *pudp; > pmd_t pmd, *pmdp; > @@ -1053,10 +1055,39 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, > } > > gpa = p->gpa; > - pgt = kvm->arch.pgtable; > - while (len != 0 && gpa < RADIX_PGTABLE_RANGE) { > + nested = NULL; > + 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) { > - 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); > p->hdr = 1; > goto copy; > @@ -1122,6 +1153,8 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, > } > } > p->gpa = gpa; > + if (nested) > + kvmhv_put_nested(nested); > > out: > mutex_unlock(&p->mutex); > diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c > index 0d7cd66..027cc16 100644 > --- a/arch/powerpc/kvm/book3s_hv_nested.c > +++ b/arch/powerpc/kvm/book3s_hv_nested.c > @@ -1182,3 +1182,18 @@ long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu) > mutex_unlock(&gp->tlb_lock); > 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; > +}
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index 84c4c0e..12007f6 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h @@ -50,6 +50,7 @@ struct rmap_nested { struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int lpid, bool create); void kvmhv_put_nested(struct kvm_nested_guest *gp); +int kvmhv_nested_next_lpid(struct kvm *kvm, int lpid); /* Power architecture requires HPT is at least 256kiB, at most 64TiB */ #define PPC_MIN_HPT_ORDER 18 diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index 52b2a57..41beb9b 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -978,6 +978,7 @@ struct debugfs_radix_state { struct kvm *kvm; struct mutex mutex; unsigned long gpa; + int lpid; int chars_left; int buf_index; char buf[128]; @@ -1019,6 +1020,7 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, struct kvm *kvm; unsigned long gpa; pgd_t *pgt; + struct kvm_nested_guest *nested; pgd_t pgd, *pgdp; pud_t pud, *pudp; pmd_t pmd, *pmdp; @@ -1053,10 +1055,39 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, } gpa = p->gpa; - pgt = kvm->arch.pgtable; - while (len != 0 && gpa < RADIX_PGTABLE_RANGE) { + nested = NULL; + 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) { - 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); p->hdr = 1; goto copy; @@ -1122,6 +1153,8 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf, } } p->gpa = gpa; + if (nested) + kvmhv_put_nested(nested); out: mutex_unlock(&p->mutex); diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index 0d7cd66..027cc16 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c @@ -1182,3 +1182,18 @@ long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu) mutex_unlock(&gp->tlb_lock); 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; +}
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. Signed-off-by: Paul Mackerras <paulus@ozlabs.org> --- arch/powerpc/include/asm/kvm_book3s_64.h | 1 + arch/powerpc/kvm/book3s_64_mmu_radix.c | 39 +++++++++++++++++++++++++++++--- arch/powerpc/kvm/book3s_hv_nested.c | 15 ++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-)