[PATCH v1 6/7] KVM: PPC: Add kvmppc_find_tce_table()

Alexey Kardashevskiy aik at ozlabs.ru
Tue Jul 15 19:25:10 EST 2014


This adds a common helper to search for a kvmppc_spapr_tce_table by
LIOBN.

This makes H_PUT_TCE and H_GET_TCE handler use this new helper.

The helper will be also used in H_PUT_TCE_INDIRECT and H_STUFF_TCE handlers.

Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
---
 arch/powerpc/kvm/book3s_64_vio_hv.c | 79 ++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 36 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index ab3f50f..79406f1 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -40,6 +40,20 @@
 
 #define TCES_PER_PAGE	(PAGE_SIZE / sizeof(u64))
 
+struct kvmppc_spapr_tce_table *kvmppc_find_tce_table(struct kvm *kvm,
+		unsigned long liobn)
+{
+	struct kvmppc_spapr_tce_table *stt;
+
+	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
+		if (stt->liobn == liobn)
+			return stt;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(kvmppc_find_tce_table);
+
 /*
  * Validates IO address.
  *
@@ -138,62 +152,55 @@ EXPORT_SYMBOL_GPL(kvmppc_tce_put);
 long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 		      unsigned long ioba, unsigned long tce)
 {
-	struct kvm *kvm = vcpu->kvm;
 	struct kvmppc_spapr_tce_table *stt;
+	long ret;
+	unsigned long idx;
 
 	/* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */
 	/* 	    liobn, ioba, tce); */
 
-	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
-		if (stt->liobn == liobn) {
-			unsigned long idx = ioba >> IOMMU_PAGE_SHIFT_4K;
-			/* udbg_printf("H_PUT_TCE: liobn 0x%lx => stt=%p  window_size=0x%x\n", */
-			/* 	    liobn, stt, stt->window_size); */
-			long ret = kvmppc_ioba_validate(stt, ioba, 1);
+	stt = kvmppc_find_tce_table(vcpu->kvm, liobn);
+	if (!stt)
+		return H_TOO_HARD;
 
-			if (ret)
-				return ret;
+	ret = kvmppc_ioba_validate(stt, ioba, 1);
+	if (ret)
+		return ret;
 
-			ret = kvmppc_tce_validate(stt, tce);
-			if (ret)
-				return ret;
+	ret = kvmppc_tce_validate(stt, tce);
+	if (ret)
+		return ret;
 
-			kvmppc_tce_put(stt, idx, tce);
+	idx = ioba >> IOMMU_PAGE_SHIFT_4K;
+	kvmppc_tce_put(stt, idx, tce);
 
-			return H_SUCCESS;
-		}
-	}
-
-	/* Didn't find the liobn, punt it to userspace */
-	return H_TOO_HARD;
+	return H_SUCCESS;
 }
 EXPORT_SYMBOL_GPL(kvmppc_h_put_tce);
 
 long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 		      unsigned long ioba)
 {
-	struct kvm *kvm = vcpu->kvm;
 	struct kvmppc_spapr_tce_table *stt;
+	long ret;
+	unsigned long idx;
+	struct page *page;
+	u64 *tbl;
 
-	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
-		if (stt->liobn == liobn) {
-			unsigned long idx = ioba >> IOMMU_PAGE_SHIFT_4K;
-			struct page *page;
-			u64 *tbl;
-			long ret = kvmppc_ioba_validate(stt, ioba, 1);
+	stt = kvmppc_find_tce_table(vcpu->kvm, liobn);
+	if (!stt)
+		return H_TOO_HARD;
 
-			if (ret)
-				return ret;
+	ret = kvmppc_ioba_validate(stt, ioba, 1);
+	if (ret)
+		return ret;
 
-			page = stt->pages[idx / TCES_PER_PAGE];
-			tbl = (u64 *)page_address(page);
+	idx = ioba >> IOMMU_PAGE_SHIFT_4K;
+	page = stt->pages[idx / TCES_PER_PAGE];
+	tbl = (u64 *)page_address(page);
 
-			vcpu->arch.gpr[4] = tbl[idx % TCES_PER_PAGE];
-			return H_SUCCESS;
-		}
-	}
+	vcpu->arch.gpr[4] = tbl[idx % TCES_PER_PAGE];
 
-	/* Didn't find the liobn, punt it to userspace */
-	return H_TOO_HARD;
+	return H_SUCCESS;
 }
 EXPORT_SYMBOL_GPL(kvmppc_h_get_tce);
-- 
2.0.0



More information about the Linuxppc-dev mailing list