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> 273f07c014SIngo Molnar #include <linux/sched/signal.h> 28f31e65e1SBenjamin Herrenschmidt #include <linux/hugetlb.h> 29f31e65e1SBenjamin Herrenschmidt #include <linux/list.h> 30f31e65e1SBenjamin Herrenschmidt #include <linux/anon_inodes.h> 31f31e65e1SBenjamin Herrenschmidt 32f31e65e1SBenjamin Herrenschmidt #include <asm/tlbflush.h> 33f31e65e1SBenjamin Herrenschmidt #include <asm/kvm_ppc.h> 34f31e65e1SBenjamin Herrenschmidt #include <asm/kvm_book3s.h> 35f64e8084SAneesh Kumar K.V #include <asm/book3s/64/mmu-hash.h> 36f31e65e1SBenjamin Herrenschmidt #include <asm/hvcall.h> 37f31e65e1SBenjamin Herrenschmidt #include <asm/synch.h> 38f31e65e1SBenjamin Herrenschmidt #include <asm/ppc-opcode.h> 39f31e65e1SBenjamin Herrenschmidt #include <asm/kvm_host.h> 40f31e65e1SBenjamin Herrenschmidt #include <asm/udbg.h> 41462ee11eSAlexey Kardashevskiy #include <asm/iommu.h> 42d3695aa4SAlexey Kardashevskiy #include <asm/tce.h> 43f31e65e1SBenjamin Herrenschmidt 44fe26e527SAlexey Kardashevskiy static unsigned long kvmppc_tce_pages(unsigned long iommu_pages) 45f31e65e1SBenjamin Herrenschmidt { 46fe26e527SAlexey Kardashevskiy return ALIGN(iommu_pages * sizeof(u64), PAGE_SIZE) / PAGE_SIZE; 47f31e65e1SBenjamin Herrenschmidt } 48f31e65e1SBenjamin Herrenschmidt 49f8626985SAlexey Kardashevskiy static unsigned long kvmppc_stt_pages(unsigned long tce_pages) 50f8626985SAlexey Kardashevskiy { 51f8626985SAlexey Kardashevskiy unsigned long stt_bytes = sizeof(struct kvmppc_spapr_tce_table) + 52f8626985SAlexey Kardashevskiy (tce_pages * sizeof(struct page *)); 53f8626985SAlexey Kardashevskiy 54f8626985SAlexey Kardashevskiy return tce_pages + ALIGN(stt_bytes, PAGE_SIZE) / PAGE_SIZE; 55f8626985SAlexey Kardashevskiy } 56f8626985SAlexey Kardashevskiy 57f8626985SAlexey Kardashevskiy static long kvmppc_account_memlimit(unsigned long stt_pages, bool inc) 58f8626985SAlexey Kardashevskiy { 59f8626985SAlexey Kardashevskiy long ret = 0; 60f8626985SAlexey Kardashevskiy 61f8626985SAlexey Kardashevskiy if (!current || !current->mm) 62f8626985SAlexey Kardashevskiy return ret; /* process exited */ 63f8626985SAlexey Kardashevskiy 64f8626985SAlexey Kardashevskiy down_write(¤t->mm->mmap_sem); 65f8626985SAlexey Kardashevskiy 66f8626985SAlexey Kardashevskiy if (inc) { 67f8626985SAlexey Kardashevskiy unsigned long locked, lock_limit; 68f8626985SAlexey Kardashevskiy 69f8626985SAlexey Kardashevskiy locked = current->mm->locked_vm + stt_pages; 70f8626985SAlexey Kardashevskiy lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; 71f8626985SAlexey Kardashevskiy if (locked > lock_limit && !capable(CAP_IPC_LOCK)) 72f8626985SAlexey Kardashevskiy ret = -ENOMEM; 73f8626985SAlexey Kardashevskiy else 74f8626985SAlexey Kardashevskiy current->mm->locked_vm += stt_pages; 75f8626985SAlexey Kardashevskiy } else { 76f8626985SAlexey Kardashevskiy if (WARN_ON_ONCE(stt_pages > current->mm->locked_vm)) 77f8626985SAlexey Kardashevskiy stt_pages = current->mm->locked_vm; 78f8626985SAlexey Kardashevskiy 79f8626985SAlexey Kardashevskiy current->mm->locked_vm -= stt_pages; 80f8626985SAlexey Kardashevskiy } 81f8626985SAlexey Kardashevskiy 82f8626985SAlexey Kardashevskiy pr_debug("[%d] RLIMIT_MEMLOCK KVM %c%ld %ld/%ld%s\n", current->pid, 83f8626985SAlexey Kardashevskiy inc ? '+' : '-', 84f8626985SAlexey Kardashevskiy stt_pages << PAGE_SHIFT, 85f8626985SAlexey Kardashevskiy current->mm->locked_vm << PAGE_SHIFT, 86f8626985SAlexey Kardashevskiy rlimit(RLIMIT_MEMLOCK), 87f8626985SAlexey Kardashevskiy ret ? " - exceeded" : ""); 88f8626985SAlexey Kardashevskiy 89f8626985SAlexey Kardashevskiy up_write(¤t->mm->mmap_sem); 90f8626985SAlexey Kardashevskiy 91f8626985SAlexey Kardashevskiy return ret; 92f8626985SAlexey Kardashevskiy } 93f8626985SAlexey Kardashevskiy 94366baf28SAlexey Kardashevskiy static void release_spapr_tce_table(struct rcu_head *head) 95f31e65e1SBenjamin Herrenschmidt { 96366baf28SAlexey Kardashevskiy struct kvmppc_spapr_tce_table *stt = container_of(head, 97366baf28SAlexey Kardashevskiy struct kvmppc_spapr_tce_table, rcu); 98fe26e527SAlexey Kardashevskiy unsigned long i, npages = kvmppc_tce_pages(stt->size); 99f31e65e1SBenjamin Herrenschmidt 100f8626985SAlexey Kardashevskiy for (i = 0; i < npages; i++) 101f31e65e1SBenjamin Herrenschmidt __free_page(stt->pages[i]); 102f31e65e1SBenjamin Herrenschmidt 103366baf28SAlexey Kardashevskiy kfree(stt); 104f31e65e1SBenjamin Herrenschmidt } 105f31e65e1SBenjamin Herrenschmidt 10611bac800SDave Jiang static int kvm_spapr_tce_fault(struct vm_fault *vmf) 107f31e65e1SBenjamin Herrenschmidt { 10811bac800SDave Jiang struct kvmppc_spapr_tce_table *stt = vmf->vma->vm_file->private_data; 109f31e65e1SBenjamin Herrenschmidt struct page *page; 110f31e65e1SBenjamin Herrenschmidt 111fe26e527SAlexey Kardashevskiy if (vmf->pgoff >= kvmppc_tce_pages(stt->size)) 112f31e65e1SBenjamin Herrenschmidt return VM_FAULT_SIGBUS; 113f31e65e1SBenjamin Herrenschmidt 114f31e65e1SBenjamin Herrenschmidt page = stt->pages[vmf->pgoff]; 115f31e65e1SBenjamin Herrenschmidt get_page(page); 116f31e65e1SBenjamin Herrenschmidt vmf->page = page; 117f31e65e1SBenjamin Herrenschmidt return 0; 118f31e65e1SBenjamin Herrenschmidt } 119f31e65e1SBenjamin Herrenschmidt 120f31e65e1SBenjamin Herrenschmidt static const struct vm_operations_struct kvm_spapr_tce_vm_ops = { 121f31e65e1SBenjamin Herrenschmidt .fault = kvm_spapr_tce_fault, 122f31e65e1SBenjamin Herrenschmidt }; 123f31e65e1SBenjamin Herrenschmidt 124f31e65e1SBenjamin Herrenschmidt static int kvm_spapr_tce_mmap(struct file *file, struct vm_area_struct *vma) 125f31e65e1SBenjamin Herrenschmidt { 126f31e65e1SBenjamin Herrenschmidt vma->vm_ops = &kvm_spapr_tce_vm_ops; 127f31e65e1SBenjamin Herrenschmidt return 0; 128f31e65e1SBenjamin Herrenschmidt } 129f31e65e1SBenjamin Herrenschmidt 130f31e65e1SBenjamin Herrenschmidt static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) 131f31e65e1SBenjamin Herrenschmidt { 132f31e65e1SBenjamin Herrenschmidt struct kvmppc_spapr_tce_table *stt = filp->private_data; 133f31e65e1SBenjamin Herrenschmidt 134366baf28SAlexey Kardashevskiy list_del_rcu(&stt->list); 135366baf28SAlexey Kardashevskiy 136366baf28SAlexey Kardashevskiy kvm_put_kvm(stt->kvm); 137366baf28SAlexey Kardashevskiy 138f8626985SAlexey Kardashevskiy kvmppc_account_memlimit( 139fe26e527SAlexey Kardashevskiy kvmppc_stt_pages(kvmppc_tce_pages(stt->size)), false); 140366baf28SAlexey Kardashevskiy call_rcu(&stt->rcu, release_spapr_tce_table); 141366baf28SAlexey Kardashevskiy 142f31e65e1SBenjamin Herrenschmidt return 0; 143f31e65e1SBenjamin Herrenschmidt } 144f31e65e1SBenjamin Herrenschmidt 14575ef9de1SAl Viro static const struct file_operations kvm_spapr_tce_fops = { 146f31e65e1SBenjamin Herrenschmidt .mmap = kvm_spapr_tce_mmap, 147f31e65e1SBenjamin Herrenschmidt .release = kvm_spapr_tce_release, 148f31e65e1SBenjamin Herrenschmidt }; 149f31e65e1SBenjamin Herrenschmidt 150f31e65e1SBenjamin Herrenschmidt long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 15158ded420SAlexey Kardashevskiy struct kvm_create_spapr_tce_64 *args) 152f31e65e1SBenjamin Herrenschmidt { 153f31e65e1SBenjamin Herrenschmidt struct kvmppc_spapr_tce_table *stt = NULL; 154fe26e527SAlexey Kardashevskiy unsigned long npages, size; 155f31e65e1SBenjamin Herrenschmidt int ret = -ENOMEM; 156f31e65e1SBenjamin Herrenschmidt int i; 157f31e65e1SBenjamin Herrenschmidt 15858ded420SAlexey Kardashevskiy if (!args->size) 15958ded420SAlexey Kardashevskiy return -EINVAL; 16058ded420SAlexey Kardashevskiy 161f31e65e1SBenjamin Herrenschmidt /* Check this LIOBN hasn't been previously allocated */ 162f31e65e1SBenjamin Herrenschmidt list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) { 163f31e65e1SBenjamin Herrenschmidt if (stt->liobn == args->liobn) 164f31e65e1SBenjamin Herrenschmidt return -EBUSY; 165f31e65e1SBenjamin Herrenschmidt } 166f31e65e1SBenjamin Herrenschmidt 1673762d45aSAlexey Kardashevskiy size = _ALIGN_UP(args->size, PAGE_SIZE >> 3); 168fe26e527SAlexey Kardashevskiy npages = kvmppc_tce_pages(size); 169f8626985SAlexey Kardashevskiy ret = kvmppc_account_memlimit(kvmppc_stt_pages(npages), true); 170f8626985SAlexey Kardashevskiy if (ret) { 171f8626985SAlexey Kardashevskiy stt = NULL; 172f8626985SAlexey Kardashevskiy goto fail; 173f8626985SAlexey Kardashevskiy } 174f31e65e1SBenjamin Herrenschmidt 1755982f084SWei Yongjun ret = -ENOMEM; 176f31e65e1SBenjamin Herrenschmidt stt = kzalloc(sizeof(*stt) + npages * sizeof(struct page *), 177f31e65e1SBenjamin Herrenschmidt GFP_KERNEL); 178f31e65e1SBenjamin Herrenschmidt if (!stt) 179f31e65e1SBenjamin Herrenschmidt goto fail; 180f31e65e1SBenjamin Herrenschmidt 181f31e65e1SBenjamin Herrenschmidt stt->liobn = args->liobn; 18258ded420SAlexey Kardashevskiy stt->page_shift = args->page_shift; 18358ded420SAlexey Kardashevskiy stt->offset = args->offset; 184fe26e527SAlexey Kardashevskiy stt->size = size; 185f31e65e1SBenjamin Herrenschmidt stt->kvm = kvm; 186f31e65e1SBenjamin Herrenschmidt 187f31e65e1SBenjamin Herrenschmidt for (i = 0; i < npages; i++) { 188f31e65e1SBenjamin Herrenschmidt stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); 189f31e65e1SBenjamin Herrenschmidt if (!stt->pages[i]) 190f31e65e1SBenjamin Herrenschmidt goto fail; 191f31e65e1SBenjamin Herrenschmidt } 192f31e65e1SBenjamin Herrenschmidt 193f31e65e1SBenjamin Herrenschmidt kvm_get_kvm(kvm); 194f31e65e1SBenjamin Herrenschmidt 195f31e65e1SBenjamin Herrenschmidt mutex_lock(&kvm->lock); 196366baf28SAlexey Kardashevskiy list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables); 197f31e65e1SBenjamin Herrenschmidt 198f31e65e1SBenjamin Herrenschmidt mutex_unlock(&kvm->lock); 199f31e65e1SBenjamin Herrenschmidt 200f31e65e1SBenjamin Herrenschmidt return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, 2012f84d5eaSYann Droneaud stt, O_RDWR | O_CLOEXEC); 202f31e65e1SBenjamin Herrenschmidt 203f31e65e1SBenjamin Herrenschmidt fail: 204f31e65e1SBenjamin Herrenschmidt if (stt) { 205f31e65e1SBenjamin Herrenschmidt for (i = 0; i < npages; i++) 206f31e65e1SBenjamin Herrenschmidt if (stt->pages[i]) 207f31e65e1SBenjamin Herrenschmidt __free_page(stt->pages[i]); 208f31e65e1SBenjamin Herrenschmidt 209f31e65e1SBenjamin Herrenschmidt kfree(stt); 210f31e65e1SBenjamin Herrenschmidt } 211f31e65e1SBenjamin Herrenschmidt return ret; 212f31e65e1SBenjamin Herrenschmidt } 213d3695aa4SAlexey Kardashevskiy 21431217db7SAlexey Kardashevskiy long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, 21531217db7SAlexey Kardashevskiy unsigned long ioba, unsigned long tce) 21631217db7SAlexey Kardashevskiy { 217*503bfcbeSAlexey Kardashevskiy struct kvmppc_spapr_tce_table *stt; 21831217db7SAlexey Kardashevskiy long ret; 21931217db7SAlexey Kardashevskiy 22031217db7SAlexey Kardashevskiy /* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */ 22131217db7SAlexey Kardashevskiy /* liobn, ioba, tce); */ 22231217db7SAlexey Kardashevskiy 223*503bfcbeSAlexey Kardashevskiy stt = kvmppc_find_table(vcpu->kvm, liobn); 22431217db7SAlexey Kardashevskiy if (!stt) 22531217db7SAlexey Kardashevskiy return H_TOO_HARD; 22631217db7SAlexey Kardashevskiy 22731217db7SAlexey Kardashevskiy ret = kvmppc_ioba_validate(stt, ioba, 1); 22831217db7SAlexey Kardashevskiy if (ret != H_SUCCESS) 22931217db7SAlexey Kardashevskiy return ret; 23031217db7SAlexey Kardashevskiy 23131217db7SAlexey Kardashevskiy ret = kvmppc_tce_validate(stt, tce); 23231217db7SAlexey Kardashevskiy if (ret != H_SUCCESS) 23331217db7SAlexey Kardashevskiy return ret; 23431217db7SAlexey Kardashevskiy 23531217db7SAlexey Kardashevskiy kvmppc_tce_put(stt, ioba >> stt->page_shift, tce); 23631217db7SAlexey Kardashevskiy 23731217db7SAlexey Kardashevskiy return H_SUCCESS; 23831217db7SAlexey Kardashevskiy } 23931217db7SAlexey Kardashevskiy EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); 24031217db7SAlexey Kardashevskiy 241d3695aa4SAlexey Kardashevskiy long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, 242d3695aa4SAlexey Kardashevskiy unsigned long liobn, unsigned long ioba, 243d3695aa4SAlexey Kardashevskiy unsigned long tce_list, unsigned long npages) 244d3695aa4SAlexey Kardashevskiy { 245d3695aa4SAlexey Kardashevskiy struct kvmppc_spapr_tce_table *stt; 246d3695aa4SAlexey Kardashevskiy long i, ret = H_SUCCESS, idx; 247d3695aa4SAlexey Kardashevskiy unsigned long entry, ua = 0; 248f8750513SDaniel Axtens u64 __user *tces; 249f8750513SDaniel Axtens u64 tce; 250d3695aa4SAlexey Kardashevskiy 251*503bfcbeSAlexey Kardashevskiy stt = kvmppc_find_table(vcpu->kvm, liobn); 252d3695aa4SAlexey Kardashevskiy if (!stt) 253d3695aa4SAlexey Kardashevskiy return H_TOO_HARD; 254d3695aa4SAlexey Kardashevskiy 255fe26e527SAlexey Kardashevskiy entry = ioba >> stt->page_shift; 256d3695aa4SAlexey Kardashevskiy /* 257d3695aa4SAlexey Kardashevskiy * SPAPR spec says that the maximum size of the list is 512 TCEs 258d3695aa4SAlexey Kardashevskiy * so the whole table fits in 4K page 259d3695aa4SAlexey Kardashevskiy */ 260d3695aa4SAlexey Kardashevskiy if (npages > 512) 261d3695aa4SAlexey Kardashevskiy return H_PARAMETER; 262d3695aa4SAlexey Kardashevskiy 263d3695aa4SAlexey Kardashevskiy if (tce_list & (SZ_4K - 1)) 264d3695aa4SAlexey Kardashevskiy return H_PARAMETER; 265d3695aa4SAlexey Kardashevskiy 266d3695aa4SAlexey Kardashevskiy ret = kvmppc_ioba_validate(stt, ioba, npages); 267d3695aa4SAlexey Kardashevskiy if (ret != H_SUCCESS) 268d3695aa4SAlexey Kardashevskiy return ret; 269d3695aa4SAlexey Kardashevskiy 270d3695aa4SAlexey Kardashevskiy idx = srcu_read_lock(&vcpu->kvm->srcu); 271d3695aa4SAlexey Kardashevskiy if (kvmppc_gpa_to_ua(vcpu->kvm, tce_list, &ua, NULL)) { 272d3695aa4SAlexey Kardashevskiy ret = H_TOO_HARD; 273d3695aa4SAlexey Kardashevskiy goto unlock_exit; 274d3695aa4SAlexey Kardashevskiy } 275d3695aa4SAlexey Kardashevskiy tces = (u64 __user *) ua; 276d3695aa4SAlexey Kardashevskiy 277d3695aa4SAlexey Kardashevskiy for (i = 0; i < npages; ++i) { 278d3695aa4SAlexey Kardashevskiy if (get_user(tce, tces + i)) { 279d3695aa4SAlexey Kardashevskiy ret = H_TOO_HARD; 280d3695aa4SAlexey Kardashevskiy goto unlock_exit; 281d3695aa4SAlexey Kardashevskiy } 282d3695aa4SAlexey Kardashevskiy tce = be64_to_cpu(tce); 283d3695aa4SAlexey Kardashevskiy 284d3695aa4SAlexey Kardashevskiy ret = kvmppc_tce_validate(stt, tce); 285d3695aa4SAlexey Kardashevskiy if (ret != H_SUCCESS) 286d3695aa4SAlexey Kardashevskiy goto unlock_exit; 287d3695aa4SAlexey Kardashevskiy 288d3695aa4SAlexey Kardashevskiy kvmppc_tce_put(stt, entry + i, tce); 289d3695aa4SAlexey Kardashevskiy } 290d3695aa4SAlexey Kardashevskiy 291d3695aa4SAlexey Kardashevskiy unlock_exit: 292d3695aa4SAlexey Kardashevskiy srcu_read_unlock(&vcpu->kvm->srcu, idx); 293d3695aa4SAlexey Kardashevskiy 294d3695aa4SAlexey Kardashevskiy return ret; 295d3695aa4SAlexey Kardashevskiy } 296d3695aa4SAlexey Kardashevskiy EXPORT_SYMBOL_GPL(kvmppc_h_put_tce_indirect); 29731217db7SAlexey Kardashevskiy 29831217db7SAlexey Kardashevskiy long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu, 29931217db7SAlexey Kardashevskiy unsigned long liobn, unsigned long ioba, 30031217db7SAlexey Kardashevskiy unsigned long tce_value, unsigned long npages) 30131217db7SAlexey Kardashevskiy { 30231217db7SAlexey Kardashevskiy struct kvmppc_spapr_tce_table *stt; 30331217db7SAlexey Kardashevskiy long i, ret; 30431217db7SAlexey Kardashevskiy 305*503bfcbeSAlexey Kardashevskiy stt = kvmppc_find_table(vcpu->kvm, liobn); 30631217db7SAlexey Kardashevskiy if (!stt) 30731217db7SAlexey Kardashevskiy return H_TOO_HARD; 30831217db7SAlexey Kardashevskiy 30931217db7SAlexey Kardashevskiy ret = kvmppc_ioba_validate(stt, ioba, npages); 31031217db7SAlexey Kardashevskiy if (ret != H_SUCCESS) 31131217db7SAlexey Kardashevskiy return ret; 31231217db7SAlexey Kardashevskiy 31331217db7SAlexey Kardashevskiy /* Check permission bits only to allow userspace poison TCE for debug */ 31431217db7SAlexey Kardashevskiy if (tce_value & (TCE_PCI_WRITE | TCE_PCI_READ)) 31531217db7SAlexey Kardashevskiy return H_PARAMETER; 31631217db7SAlexey Kardashevskiy 31731217db7SAlexey Kardashevskiy for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) 31831217db7SAlexey Kardashevskiy kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value); 31931217db7SAlexey Kardashevskiy 32031217db7SAlexey Kardashevskiy return H_SUCCESS; 32131217db7SAlexey Kardashevskiy } 32231217db7SAlexey Kardashevskiy EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce); 323