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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ struct rmap_nested {
struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
					  bool create);
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 */
#define H_TLBIE_P1_ENC(ric, prs, r)	(___PPC_RIC(ric) | ___PPC_PRS(prs) | \
+36 −3
Original line number Diff line number Diff line
@@ -1002,6 +1002,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];
@@ -1043,6 +1044,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;
@@ -1077,10 +1079,39 @@ static ssize_t debugfs_radix_read(struct file *file, char __user *buf,
	}

	gpa = p->gpa;
	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;
	while (len != 0 && gpa < RADIX_PGTABLE_RANGE) {
			} 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->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;
@@ -1146,6 +1177,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);
+15 −0
Original line number Diff line number Diff line
@@ -1274,3 +1274,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;
}