1f31e65e1SBenjamin Herrenschmidt /* 2f31e65e1SBenjamin Herrenschmidt * This program is free software; you can redistribute it and/or modify 3f31e65e1SBenjamin Herrenschmidt * it under the terms of the GNU General Public License, version 2, as 4f31e65e1SBenjamin Herrenschmidt * published by the Free Software Foundation. 5f31e65e1SBenjamin Herrenschmidt * 6f31e65e1SBenjamin Herrenschmidt * This program is distributed in the hope that it will be useful, 7f31e65e1SBenjamin Herrenschmidt * but WITHOUT ANY WARRANTY; without even the implied warranty of 8f31e65e1SBenjamin Herrenschmidt * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9f31e65e1SBenjamin Herrenschmidt * GNU General Public License for more details. 10f31e65e1SBenjamin Herrenschmidt * 11f31e65e1SBenjamin Herrenschmidt * You should have received a copy of the GNU General Public License 12f31e65e1SBenjamin Herrenschmidt * along with this program; if not, write to the Free Software 13f31e65e1SBenjamin Herrenschmidt * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 14f31e65e1SBenjamin Herrenschmidt * 15f31e65e1SBenjamin Herrenschmidt * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> 16f31e65e1SBenjamin Herrenschmidt * Copyright 2011 David Gibson, IBM Corporation <dwg@au1.ibm.com> 17d3695aa4SAlexey Kardashevskiy * Copyright 2016 Alexey Kardashevskiy, IBM Corporation <aik@au1.ibm.com> 18f31e65e1SBenjamin Herrenschmidt */ 19f31e65e1SBenjamin Herrenschmidt 20f31e65e1SBenjamin Herrenschmidt #include <linux/types.h> 21f31e65e1SBenjamin Herrenschmidt #include <linux/string.h> 22f31e65e1SBenjamin Herrenschmidt #include <linux/kvm.h> 23f31e65e1SBenjamin Herrenschmidt #include <linux/kvm_host.h> 24f31e65e1SBenjamin Herrenschmidt #include <linux/highmem.h> 25f31e65e1SBenjamin Herrenschmidt #include <linux/gfp.h> 26f31e65e1SBenjamin Herrenschmidt #include <linux/slab.h> 27f31e65e1SBenjamin Herrenschmidt #include <linux/hugetlb.h> 28f31e65e1SBenjamin Herrenschmidt #include <linux/list.h> 29f31e65e1SBenjamin Herrenschmidt #include <linux/anon_inodes.h> 30f31e65e1SBenjamin Herrenschmidt 31f31e65e1SBenjamin Herrenschmidt #include <asm/tlbflush.h> 32f31e65e1SBenjamin Herrenschmidt #include <asm/kvm_ppc.h> 33f31e65e1SBenjamin Herrenschmidt #include <asm/kvm_book3s.h> 34f64e8084SAneesh Kumar K.V #include <asm/book3s/64/mmu-hash.h> 35f31e65e1SBenjamin Herrenschmidt #include <asm/hvcall.h> 36f31e65e1SBenjamin Herrenschmidt #include <asm/synch.h> 37f31e65e1SBenjamin Herrenschmidt #include <asm/ppc-opcode.h> 38f31e65e1SBenjamin Herrenschmidt #include <asm/kvm_host.h> 39f31e65e1SBenjamin Herrenschmidt #include <asm/udbg.h> 40462ee11eSAlexey Kardashevskiy #include <asm/iommu.h> 41d3695aa4SAlexey Kardashevskiy #include <asm/tce.h> 42f31e65e1SBenjamin Herrenschmidt 43fe26e527SAlexey Kardashevskiy static unsigned long kvmppc_tce_pages(unsigned long iommu_pages) 44f31e65e1SBenjamin Herrenschmidt { 45fe26e527SAlexey Kardashevskiy return ALIGN(iommu_pages * sizeof(u64), PAGE_SIZE) / PAGE_SIZE; 46f31e65e1SBenjamin Herrenschmidt } 47f31e65e1SBenjamin Herrenschmidt 48f8626985SAlexey Kardashevskiy static unsigned long kvmppc_stt_pages(unsigned long tce_pages) 49f8626985SAlexey Kardashevskiy { 50f8626985SAlexey Kardashevskiy unsigned long stt_bytes = sizeof(struct kvmppc_spapr_tce_table) + 51f8626985SAlexey Kardashevskiy (tce_pages * sizeof(struct page *)); 52f8626985SAlexey Kardashevskiy 53f8626985SAlexey Kardashevskiy return tce_pages + ALIGN(stt_bytes, PAGE_SIZE) / PAGE_SIZE; 54f8626985SAlexey Kardashevskiy } 55f8626985SAlexey Kardashevskiy 56f8626985SAlexey Kardashevskiy static long kvmppc_account_memlimit(unsigned long stt_pages, bool inc) 57f8626985SAlexey Kardashevskiy { 58f8626985SAlexey Kardashevskiy long ret = 0; 59f8626985SAlexey Kardashevskiy 60f8626985SAlexey Kardashevskiy if (!current || !current->mm) 61f8626985SAlexey Kardashevskiy return ret; /* process exited */ 62f8626985SAlexey Kardashevskiy 63f8626985SAlexey Kardashevskiy down_write(¤t->mm->mmap_sem); 64f8626985SAlexey Kardashevskiy 65f8626985SAlexey Kardashevskiy if (inc) { 66f8626985SAlexey Kardashevskiy unsigned long locked, lock_limit; 67f8626985SAlexey Kardashevskiy 68f8626985SAlexey Kardashevskiy locked = current->mm->locked_vm + stt_pages; 69f8626985SAlexey Kardashevskiy lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; 70f8626985SAlexey Kardashevskiy if (locked > lock_limit && !capable(CAP_IPC_LOCK)) 71f8626985SAlexey Kardashevskiy ret = -ENOMEM; 72f8626985SAlexey Kardashevskiy else 73f8626985SAlexey Kardashevskiy current->mm->locked_vm += stt_pages; 74f8626985SAlexey Kardashevskiy } else { 75f8626985SAlexey Kardashevskiy if (WARN_ON_ONCE(stt_pages > current->mm->locked_vm)) 76f8626985SAlexey Kardashevskiy stt_pages = current->mm->locked_vm; 77f8626985SAlexey Kardashevskiy 78f8626985SAlexey Kardashevskiy current->mm->locked_vm -= stt_pages; 79f8626985SAlexey Kardashevskiy } 80f8626985SAlexey Kardashevskiy 81f8626985SAlexey Kardashevskiy pr_debug("[%d] RLIMIT_MEMLOCK KVM %c%ld %ld/%ld%s\n", current->pid, 82f8626985SAlexey Kardashevskiy inc ? '+' : '-', 83f8626985SAlexey Kardashevskiy stt_pages << PAGE_SHIFT, 84f8626985SAlexey Kardashevskiy current->mm->locked_vm << PAGE_SHIFT, 85f8626985SAlexey Kardashevskiy rlimit(RLIMIT_MEMLOCK), 86f8626985SAlexey Kardashevskiy ret ? " - exceeded" : ""); 87f8626985SAlexey Kardashevskiy 88f8626985SAlexey Kardashevskiy up_write(¤t->mm->mmap_sem); 89f8626985SAlexey Kardashevskiy 90f8626985SAlexey Kardashevskiy return ret; 91f8626985SAlexey Kardashevskiy } 92f8626985SAlexey Kardashevskiy 93366baf28SAlexey Kardashevskiy static void release_spapr_tce_table(struct rcu_head *head) 94f31e65e1SBenjamin Herrenschmidt { 95366baf28SAlexey Kardashevskiy struct kvmppc_spapr_tce_table *stt = container_of(head, 96366baf28SAlexey Kardashevskiy struct kvmppc_spapr_tce_table, rcu); 97fe26e527SAlexey Kardashevskiy unsigned long i, npages = kvmppc_tce_pages(stt->size); 98f31e65e1SBenjamin Herrenschmidt 99f8626985SAlexey Kardashevskiy for (i = 0; i < npages; i++) 100f31e65e1SBenjamin Herrenschmidt __free_page(stt->pages[i]); 101f31e65e1SBenjamin Herrenschmidt 102366baf28SAlexey Kardashevskiy kfree(stt); 103f31e65e1SBenjamin Herrenschmidt } 104f31e65e1SBenjamin Herrenschmidt 105*11bac800SDave Jiang static int kvm_spapr_tce_fault(struct vm_fault *vmf) 106f31e65e1SBenjamin Herrenschmidt { 107*11bac800SDave Jiang struct kvmppc_spapr_tce_table *stt = vmf->vma->vm_file->private_data; 108f31e65e1SBenjamin Herrenschmidt struct page *page; 109f31e65e1SBenjamin Herrenschmidt 110fe26e527SAlexey Kardashevskiy if (vmf->pgoff >= kvmppc_tce_pages(stt->size)) 111f31e65e1SBenjamin Herrenschmidt return VM_FAULT_SIGBUS; 112f31e65e1SBenjamin Herrenschmidt 113f31e65e1SBenjamin Herrenschmidt page = stt->pages[vmf->pgoff]; 114f31e65e1SBenjamin Herrenschmidt get_page(page); 115f31e65e1SBenjamin Herrenschmidt vmf->page = page; 116f31e65e1SBenjamin Herrenschmidt return 0; 117f31e65e1SBenjamin Herrenschmidt } 118f31e65e1SBenjamin Herrenschmidt 119f31e65e1SBenjamin Herrenschmidt static const struct vm_operations_struct kvm_spapr_tce_vm_ops = { 120f31e65e1SBenjamin Herrenschmidt .fault = kvm_spapr_tce_fault, 121f31e65e1SBenjamin Herrenschmidt }; 122f31e65e1SBenjamin Herrenschmidt 123f31e65e1SBenjamin Herrenschmidt static int kvm_spapr_tce_mmap(struct file *file, struct vm_area_struct *vma) 124f31e65e1SBenjamin Herrenschmidt { 125f31e65e1SBenjamin Herrenschmidt vma->vm_ops = &kvm_spapr_tce_vm_ops; 126f31e65e1SBenjamin Herrenschmidt return 0; 127f31e65e1SBenjamin Herrenschmidt } 128f31e65e1SBenjamin Herrenschmidt 129f31e65e1SBenjamin Herrenschmidt static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) 130f31e65e1SBenjamin Herrenschmidt { 131f31e65e1SBenjamin Herrenschmidt struct kvmppc_spapr_tce_table *stt = filp->private_data; 132f31e65e1SBenjamin Herrenschmidt 133366baf28SAlexey Kardashevskiy list_del_rcu(&stt->list); 134366baf28SAlexey Kardashevskiy 135366baf28SAlexey Kardashevskiy kvm_put_kvm(stt->kvm); 136366baf28SAlexey Kardashevskiy 137f8626985SAlexey Kardashevskiy kvmppc_account_memlimit( 138fe26e527SAlexey Kardashevskiy kvmppc_stt_pages(kvmppc_tce_pages(stt->size)), false); 139366baf28SAlexey Kardashevskiy call_rcu(&stt->rcu, release_spapr_tce_table); 140366baf28SAlexey Kardashevskiy 141f31e65e1SBenjamin Herrenschmidt return 0; 142f31e65e1SBenjamin Herrenschmidt } 143f31e65e1SBenjamin Herrenschmidt 14475ef9de1SAl Viro static const struct file_operations kvm_spapr_tce_fops = { 145f31e65e1SBenjamin Herrenschmidt .mmap = kvm_spapr_tce_mmap, 146f31e65e1SBenjamin Herrenschmidt .release = kvm_spapr_tce_release, 147f31e65e1SBenjamin Herrenschmidt }; 148f31e65e1SBenjamin Herrenschmidt 149f31e65e1SBenjamin Herrenschmidt long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 15058ded420SAlexey Kardashevskiy struct kvm_create_spapr_tce_64 *args) 151f31e65e1SBenjamin Herrenschmidt { 152f31e65e1SBenjamin Herrenschmidt struct kvmppc_spapr_tce_table *stt = NULL; 153fe26e527SAlexey Kardashevskiy unsigned long npages, size; 154f31e65e1SBenjamin Herrenschmidt int ret = -ENOMEM; 155f31e65e1SBenjamin Herrenschmidt int i; 156f31e65e1SBenjamin Herrenschmidt 15758ded420SAlexey Kardashevskiy if (!args->size) 15858ded420SAlexey Kardashevskiy return -EINVAL; 15958ded420SAlexey Kardashevskiy 160f31e65e1SBenjamin Herrenschmidt /* Check this LIOBN hasn't been previously allocated */ 161f31e65e1SBenjamin Herrenschmidt list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) { 162f31e65e1SBenjamin Herrenschmidt if (stt->liobn == args->liobn) 163f31e65e1SBenjamin Herrenschmidt return -EBUSY; 164f31e65e1SBenjamin Herrenschmidt } 165f31e65e1SBenjamin Herrenschmidt 16658ded420SAlexey Kardashevskiy size = args->size; 167fe26e527SAlexey Kardashevskiy npages = kvmppc_tce_pages(size); 168f8626985SAlexey Kardashevskiy ret = kvmppc_account_memlimit(kvmppc_stt_pages(npages), true); 169f8626985SAlexey Kardashevskiy if (ret) { 170f8626985SAlexey Kardashevskiy stt = NULL; 171f8626985SAlexey Kardashevskiy goto fail; 172f8626985SAlexey Kardashevskiy } 173f31e65e1SBenjamin Herrenschmidt 1745982f084SWei Yongjun ret = -ENOMEM; 175f31e65e1SBenjamin Herrenschmidt stt = kzalloc(sizeof(*stt) + npages * sizeof(struct page *), 176f31e65e1SBenjamin Herrenschmidt GFP_KERNEL); 177f31e65e1SBenjamin Herrenschmidt if (!stt) 178f31e65e1SBenjamin Herrenschmidt goto fail; 179f31e65e1SBenjamin Herrenschmidt 180f31e65e1SBenjamin Herrenschmidt stt->liobn = args->liobn; 18158ded420SAlexey Kardashevskiy stt->page_shift = args->page_shift; 18258ded420SAlexey Kardashevskiy stt->offset = args->offset; 183fe26e527SAlexey Kardashevskiy stt->size = size; 184f31e65e1SBenjamin Herrenschmidt stt->kvm = kvm; 185f31e65e1SBenjamin Herrenschmidt 186f31e65e1SBenjamin Herrenschmidt for (i = 0; i < npages; i++) { 187f31e65e1SBenjamin Herrenschmidt stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); 188f31e65e1SBenjamin Herrenschmidt if (!stt->pages[i]) 189f31e65e1SBenjamin Herrenschmidt goto fail; 190f31e65e1SBenjamin Herrenschmidt } 191f31e65e1SBenjamin Herrenschmidt 192f31e65e1SBenjamin Herrenschmidt kvm_get_kvm(kvm); 193f31e65e1SBenjamin Herrenschmidt 194f31e65e1SBenjamin Herrenschmidt mutex_lock(&kvm->lock); 195366baf28SAlexey Kardashevskiy list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables); 196f31e65e1SBenjamin Herrenschmidt 197f31e65e1SBenjamin Herrenschmidt mutex_unlock(&kvm->lock); 198f31e65e1SBenjamin Herrenschmidt 199f31e65e1SBenjamin Herrenschmidt return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, 2002f84d5eaSYann Droneaud stt, O_RDWR | O_CLOEXEC); 201f31e65e1SBenjamin Herrenschmidt 202f31e65e1SBenjamin Herrenschmidt fail: 203f31e65e1SBenjamin Herrenschmidt if (stt) { 204f31e65e1SBenjamin Herrenschmidt for (i = 0; i < npages; i++) 205f31e65e1SBenjamin Herrenschmidt if (stt->pages[i]) 206f31e65e1SBenjamin Herrenschmidt __free_page(stt->pages[i]); 207f31e65e1SBenjamin Herrenschmidt 208f31e65e1SBenjamin Herrenschmidt kfree(stt); 209f31e65e1SBenjamin Herrenschmidt } 210f31e65e1SBenjamin Herrenschmidt return ret; 211f31e65e1SBenjamin Herrenschmidt } 212d3695aa4SAlexey Kardashevskiy 21331217db7SAlexey Kardashevskiy long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, 21431217db7SAlexey Kardashevskiy unsigned long ioba, unsigned long tce) 21531217db7SAlexey Kardashevskiy { 21631217db7SAlexey Kardashevskiy struct kvmppc_spapr_tce_table *stt = kvmppc_find_table(vcpu, liobn); 21731217db7SAlexey Kardashevskiy long ret; 21831217db7SAlexey Kardashevskiy 21931217db7SAlexey Kardashevskiy /* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */ 22031217db7SAlexey Kardashevskiy /* liobn, ioba, tce); */ 22131217db7SAlexey Kardashevskiy 22231217db7SAlexey Kardashevskiy if (!stt) 22331217db7SAlexey Kardashevskiy return H_TOO_HARD; 22431217db7SAlexey Kardashevskiy 22531217db7SAlexey Kardashevskiy ret = kvmppc_ioba_validate(stt, ioba, 1); 22631217db7SAlexey Kardashevskiy if (ret != H_SUCCESS) 22731217db7SAlexey Kardashevskiy return ret; 22831217db7SAlexey Kardashevskiy 22931217db7SAlexey Kardashevskiy ret = kvmppc_tce_validate(stt, tce); 23031217db7SAlexey Kardashevskiy if (ret != H_SUCCESS) 23131217db7SAlexey Kardashevskiy return ret; 23231217db7SAlexey Kardashevskiy 23331217db7SAlexey Kardashevskiy kvmppc_tce_put(stt, ioba >> stt->page_shift, tce); 23431217db7SAlexey Kardashevskiy 23531217db7SAlexey Kardashevskiy return H_SUCCESS; 23631217db7SAlexey Kardashevskiy } 23731217db7SAlexey Kardashevskiy EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); 23831217db7SAlexey Kardashevskiy 239d3695aa4SAlexey Kardashevskiy long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, 240d3695aa4SAlexey Kardashevskiy unsigned long liobn, unsigned long ioba, 241d3695aa4SAlexey Kardashevskiy unsigned long tce_list, unsigned long npages) 242d3695aa4SAlexey Kardashevskiy { 243d3695aa4SAlexey Kardashevskiy struct kvmppc_spapr_tce_table *stt; 244d3695aa4SAlexey Kardashevskiy long i, ret = H_SUCCESS, idx; 245d3695aa4SAlexey Kardashevskiy unsigned long entry, ua = 0; 246f8750513SDaniel Axtens u64 __user *tces; 247f8750513SDaniel Axtens u64 tce; 248d3695aa4SAlexey Kardashevskiy 249d3695aa4SAlexey Kardashevskiy stt = kvmppc_find_table(vcpu, liobn); 250d3695aa4SAlexey Kardashevskiy if (!stt) 251d3695aa4SAlexey Kardashevskiy return H_TOO_HARD; 252d3695aa4SAlexey Kardashevskiy 253fe26e527SAlexey Kardashevskiy entry = ioba >> stt->page_shift; 254d3695aa4SAlexey Kardashevskiy /* 255d3695aa4SAlexey Kardashevskiy * SPAPR spec says that the maximum size of the list is 512 TCEs 256d3695aa4SAlexey Kardashevskiy * so the whole table fits in 4K page 257d3695aa4SAlexey Kardashevskiy */ 258d3695aa4SAlexey Kardashevskiy if (npages > 512) 259d3695aa4SAlexey Kardashevskiy return H_PARAMETER; 260d3695aa4SAlexey Kardashevskiy 261d3695aa4SAlexey Kardashevskiy if (tce_list & (SZ_4K - 1)) 262d3695aa4SAlexey Kardashevskiy return H_PARAMETER; 263d3695aa4SAlexey Kardashevskiy 264d3695aa4SAlexey Kardashevskiy ret = kvmppc_ioba_validate(stt, ioba, npages); 265d3695aa4SAlexey Kardashevskiy if (ret != H_SUCCESS) 266d3695aa4SAlexey Kardashevskiy return ret; 267d3695aa4SAlexey Kardashevskiy 268d3695aa4SAlexey Kardashevskiy idx = srcu_read_lock(&vcpu->kvm->srcu); 269d3695aa4SAlexey Kardashevskiy if (kvmppc_gpa_to_ua(vcpu->kvm, tce_list, &ua, NULL)) { 270d3695aa4SAlexey Kardashevskiy ret = H_TOO_HARD; 271d3695aa4SAlexey Kardashevskiy goto unlock_exit; 272d3695aa4SAlexey Kardashevskiy } 273d3695aa4SAlexey Kardashevskiy tces = (u64 __user *) ua; 274d3695aa4SAlexey Kardashevskiy 275d3695aa4SAlexey Kardashevskiy for (i = 0; i < npages; ++i) { 276d3695aa4SAlexey Kardashevskiy if (get_user(tce, tces + i)) { 277d3695aa4SAlexey Kardashevskiy ret = H_TOO_HARD; 278d3695aa4SAlexey Kardashevskiy goto unlock_exit; 279d3695aa4SAlexey Kardashevskiy } 280d3695aa4SAlexey Kardashevskiy tce = be64_to_cpu(tce); 281d3695aa4SAlexey Kardashevskiy 282d3695aa4SAlexey Kardashevskiy ret = kvmppc_tce_validate(stt, tce); 283d3695aa4SAlexey Kardashevskiy if (ret != H_SUCCESS) 284d3695aa4SAlexey Kardashevskiy goto unlock_exit; 285d3695aa4SAlexey Kardashevskiy 286d3695aa4SAlexey Kardashevskiy kvmppc_tce_put(stt, entry + i, tce); 287d3695aa4SAlexey Kardashevskiy } 288d3695aa4SAlexey Kardashevskiy 289d3695aa4SAlexey Kardashevskiy unlock_exit: 290d3695aa4SAlexey Kardashevskiy srcu_read_unlock(&vcpu->kvm->srcu, idx); 291d3695aa4SAlexey Kardashevskiy 292d3695aa4SAlexey Kardashevskiy return ret; 293d3695aa4SAlexey Kardashevskiy } 294d3695aa4SAlexey Kardashevskiy EXPORT_SYMBOL_GPL(kvmppc_h_put_tce_indirect); 29531217db7SAlexey Kardashevskiy 29631217db7SAlexey Kardashevskiy long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu, 29731217db7SAlexey Kardashevskiy unsigned long liobn, unsigned long ioba, 29831217db7SAlexey Kardashevskiy unsigned long tce_value, unsigned long npages) 29931217db7SAlexey Kardashevskiy { 30031217db7SAlexey Kardashevskiy struct kvmppc_spapr_tce_table *stt; 30131217db7SAlexey Kardashevskiy long i, ret; 30231217db7SAlexey Kardashevskiy 30331217db7SAlexey Kardashevskiy stt = kvmppc_find_table(vcpu, liobn); 30431217db7SAlexey Kardashevskiy if (!stt) 30531217db7SAlexey Kardashevskiy return H_TOO_HARD; 30631217db7SAlexey Kardashevskiy 30731217db7SAlexey Kardashevskiy ret = kvmppc_ioba_validate(stt, ioba, npages); 30831217db7SAlexey Kardashevskiy if (ret != H_SUCCESS) 30931217db7SAlexey Kardashevskiy return ret; 31031217db7SAlexey Kardashevskiy 31131217db7SAlexey Kardashevskiy /* Check permission bits only to allow userspace poison TCE for debug */ 31231217db7SAlexey Kardashevskiy if (tce_value & (TCE_PCI_WRITE | TCE_PCI_READ)) 31331217db7SAlexey Kardashevskiy return H_PARAMETER; 31431217db7SAlexey Kardashevskiy 31531217db7SAlexey Kardashevskiy for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) 31631217db7SAlexey Kardashevskiy kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value); 31731217db7SAlexey Kardashevskiy 31831217db7SAlexey Kardashevskiy return H_SUCCESS; 31931217db7SAlexey Kardashevskiy } 32031217db7SAlexey Kardashevskiy EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce); 321