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 <a...@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 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev