Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kvm/book3s: Make kernel emulated H_PUT_TCE available for "PR" KVM

There is nothing in the code for emulating TCE tables in the kernel
that prevents it from working on "PR" KVM... other than ifdef's and
location of the code.

This and moves the bulk of the code there to a new file called
book3s_64_vio.c.

This speeds things up a bit on my G5.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[agraf: fix for hv kvm, 32bit, whitespace]
Signed-off-by: Alexander Graf <agraf@suse.de>

authored by

Benjamin Herrenschmidt and committed by
Alexander Graf
f31e65e1 4444aa5f

+191 -112
+3 -1
arch/powerpc/include/asm/kvm_host.h
··· 237 237 unsigned long vrma_slb_v; 238 238 int rma_setup_done; 239 239 int using_mmu_notifiers; 240 - struct list_head spapr_tce_tables; 241 240 spinlock_t slot_phys_lock; 242 241 unsigned long *slot_phys[KVM_MEM_SLOTS_NUM]; 243 242 int slot_npages[KVM_MEM_SLOTS_NUM]; ··· 244 245 struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; 245 246 struct kvmppc_linear_info *hpt_li; 246 247 #endif /* CONFIG_KVM_BOOK3S_64_HV */ 248 + #ifdef CONFIG_PPC_BOOK3S_64 249 + struct list_head spapr_tce_tables; 250 + #endif 247 251 }; 248 252 249 253 /*
+2
arch/powerpc/include/asm/kvm_ppc.h
··· 126 126 extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu); 127 127 extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 128 128 struct kvm_create_spapr_tce *args); 129 + extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, 130 + unsigned long ioba, unsigned long tce); 129 131 extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, 130 132 struct kvm_allocate_rma *rma); 131 133 extern struct kvmppc_linear_info *kvm_alloc_rma(void);
+2
arch/powerpc/kvm/Makefile
··· 54 54 book3s_paired_singles.o \ 55 55 book3s_pr.o \ 56 56 book3s_pr_papr.o \ 57 + book3s_64_vio_hv.o \ 57 58 book3s_emulate.o \ 58 59 book3s_interrupts.o \ 59 60 book3s_mmu_hpte.o \ ··· 79 78 powerpc.o \ 80 79 emulate.o \ 81 80 book3s.o \ 81 + book3s_64_vio.o \ 82 82 $(kvm-book3s_64-objs-y) 83 83 84 84 kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-module-objs)
+150
arch/powerpc/kvm/book3s_64_vio.c
··· 1 + /* 2 + * This program is free software; you can redistribute it and/or modify 3 + * it under the terms of the GNU General Public License, version 2, as 4 + * published by the Free Software Foundation. 5 + * 6 + * This program is distributed in the hope that it will be useful, 7 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 + * GNU General Public License for more details. 10 + * 11 + * You should have received a copy of the GNU General Public License 12 + * along with this program; if not, write to the Free Software 13 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 14 + * 15 + * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> 16 + * Copyright 2011 David Gibson, IBM Corporation <dwg@au1.ibm.com> 17 + */ 18 + 19 + #include <linux/types.h> 20 + #include <linux/string.h> 21 + #include <linux/kvm.h> 22 + #include <linux/kvm_host.h> 23 + #include <linux/highmem.h> 24 + #include <linux/gfp.h> 25 + #include <linux/slab.h> 26 + #include <linux/hugetlb.h> 27 + #include <linux/list.h> 28 + #include <linux/anon_inodes.h> 29 + 30 + #include <asm/tlbflush.h> 31 + #include <asm/kvm_ppc.h> 32 + #include <asm/kvm_book3s.h> 33 + #include <asm/mmu-hash64.h> 34 + #include <asm/hvcall.h> 35 + #include <asm/synch.h> 36 + #include <asm/ppc-opcode.h> 37 + #include <asm/kvm_host.h> 38 + #include <asm/udbg.h> 39 + 40 + #define TCES_PER_PAGE (PAGE_SIZE / sizeof(u64)) 41 + 42 + static long kvmppc_stt_npages(unsigned long window_size) 43 + { 44 + return ALIGN((window_size >> SPAPR_TCE_SHIFT) 45 + * sizeof(u64), PAGE_SIZE) / PAGE_SIZE; 46 + } 47 + 48 + static void release_spapr_tce_table(struct kvmppc_spapr_tce_table *stt) 49 + { 50 + struct kvm *kvm = stt->kvm; 51 + int i; 52 + 53 + mutex_lock(&kvm->lock); 54 + list_del(&stt->list); 55 + for (i = 0; i < kvmppc_stt_npages(stt->window_size); i++) 56 + __free_page(stt->pages[i]); 57 + kfree(stt); 58 + mutex_unlock(&kvm->lock); 59 + 60 + kvm_put_kvm(kvm); 61 + } 62 + 63 + static int kvm_spapr_tce_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 64 + { 65 + struct kvmppc_spapr_tce_table *stt = vma->vm_file->private_data; 66 + struct page *page; 67 + 68 + if (vmf->pgoff >= kvmppc_stt_npages(stt->window_size)) 69 + return VM_FAULT_SIGBUS; 70 + 71 + page = stt->pages[vmf->pgoff]; 72 + get_page(page); 73 + vmf->page = page; 74 + return 0; 75 + } 76 + 77 + static const struct vm_operations_struct kvm_spapr_tce_vm_ops = { 78 + .fault = kvm_spapr_tce_fault, 79 + }; 80 + 81 + static int kvm_spapr_tce_mmap(struct file *file, struct vm_area_struct *vma) 82 + { 83 + vma->vm_ops = &kvm_spapr_tce_vm_ops; 84 + return 0; 85 + } 86 + 87 + static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) 88 + { 89 + struct kvmppc_spapr_tce_table *stt = filp->private_data; 90 + 91 + release_spapr_tce_table(stt); 92 + return 0; 93 + } 94 + 95 + static struct file_operations kvm_spapr_tce_fops = { 96 + .mmap = kvm_spapr_tce_mmap, 97 + .release = kvm_spapr_tce_release, 98 + }; 99 + 100 + long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 101 + struct kvm_create_spapr_tce *args) 102 + { 103 + struct kvmppc_spapr_tce_table *stt = NULL; 104 + long npages; 105 + int ret = -ENOMEM; 106 + int i; 107 + 108 + /* Check this LIOBN hasn't been previously allocated */ 109 + list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) { 110 + if (stt->liobn == args->liobn) 111 + return -EBUSY; 112 + } 113 + 114 + npages = kvmppc_stt_npages(args->window_size); 115 + 116 + stt = kzalloc(sizeof(*stt) + npages * sizeof(struct page *), 117 + GFP_KERNEL); 118 + if (!stt) 119 + goto fail; 120 + 121 + stt->liobn = args->liobn; 122 + stt->window_size = args->window_size; 123 + stt->kvm = kvm; 124 + 125 + for (i = 0; i < npages; i++) { 126 + stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); 127 + if (!stt->pages[i]) 128 + goto fail; 129 + } 130 + 131 + kvm_get_kvm(kvm); 132 + 133 + mutex_lock(&kvm->lock); 134 + list_add(&stt->list, &kvm->arch.spapr_tce_tables); 135 + 136 + mutex_unlock(&kvm->lock); 137 + 138 + return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, 139 + stt, O_RDWR); 140 + 141 + fail: 142 + if (stt) { 143 + for (i = 0; i < npages; i++) 144 + if (stt->pages[i]) 145 + __free_page(stt->pages[i]); 146 + 147 + kfree(stt); 148 + } 149 + return ret; 150 + }
+3
arch/powerpc/kvm/book3s_64_vio_hv.c
··· 38 38 39 39 #define TCES_PER_PAGE (PAGE_SIZE / sizeof(u64)) 40 40 41 + /* WARNING: This will be called in real-mode on HV KVM and virtual 42 + * mode on PR KVM 43 + */ 41 44 long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, 42 45 unsigned long ioba, unsigned long tce) 43 46 {
-109
arch/powerpc/kvm/book3s_hv.c
··· 1093 1093 return r; 1094 1094 } 1095 1095 1096 - static long kvmppc_stt_npages(unsigned long window_size) 1097 - { 1098 - return ALIGN((window_size >> SPAPR_TCE_SHIFT) 1099 - * sizeof(u64), PAGE_SIZE) / PAGE_SIZE; 1100 - } 1101 - 1102 - static void release_spapr_tce_table(struct kvmppc_spapr_tce_table *stt) 1103 - { 1104 - struct kvm *kvm = stt->kvm; 1105 - int i; 1106 - 1107 - mutex_lock(&kvm->lock); 1108 - list_del(&stt->list); 1109 - for (i = 0; i < kvmppc_stt_npages(stt->window_size); i++) 1110 - __free_page(stt->pages[i]); 1111 - kfree(stt); 1112 - mutex_unlock(&kvm->lock); 1113 - 1114 - kvm_put_kvm(kvm); 1115 - } 1116 - 1117 - static int kvm_spapr_tce_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 1118 - { 1119 - struct kvmppc_spapr_tce_table *stt = vma->vm_file->private_data; 1120 - struct page *page; 1121 - 1122 - if (vmf->pgoff >= kvmppc_stt_npages(stt->window_size)) 1123 - return VM_FAULT_SIGBUS; 1124 - 1125 - page = stt->pages[vmf->pgoff]; 1126 - get_page(page); 1127 - vmf->page = page; 1128 - return 0; 1129 - } 1130 - 1131 - static const struct vm_operations_struct kvm_spapr_tce_vm_ops = { 1132 - .fault = kvm_spapr_tce_fault, 1133 - }; 1134 - 1135 - static int kvm_spapr_tce_mmap(struct file *file, struct vm_area_struct *vma) 1136 - { 1137 - vma->vm_ops = &kvm_spapr_tce_vm_ops; 1138 - return 0; 1139 - } 1140 - 1141 - static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) 1142 - { 1143 - struct kvmppc_spapr_tce_table *stt = filp->private_data; 1144 - 1145 - release_spapr_tce_table(stt); 1146 - return 0; 1147 - } 1148 - 1149 - static struct file_operations kvm_spapr_tce_fops = { 1150 - .mmap = kvm_spapr_tce_mmap, 1151 - .release = kvm_spapr_tce_release, 1152 - }; 1153 - 1154 - long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 1155 - struct kvm_create_spapr_tce *args) 1156 - { 1157 - struct kvmppc_spapr_tce_table *stt = NULL; 1158 - long npages; 1159 - int ret = -ENOMEM; 1160 - int i; 1161 - 1162 - /* Check this LIOBN hasn't been previously allocated */ 1163 - list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) { 1164 - if (stt->liobn == args->liobn) 1165 - return -EBUSY; 1166 - } 1167 - 1168 - npages = kvmppc_stt_npages(args->window_size); 1169 - 1170 - stt = kzalloc(sizeof(*stt) + npages* sizeof(struct page *), 1171 - GFP_KERNEL); 1172 - if (!stt) 1173 - goto fail; 1174 - 1175 - stt->liobn = args->liobn; 1176 - stt->window_size = args->window_size; 1177 - stt->kvm = kvm; 1178 - 1179 - for (i = 0; i < npages; i++) { 1180 - stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); 1181 - if (!stt->pages[i]) 1182 - goto fail; 1183 - } 1184 - 1185 - kvm_get_kvm(kvm); 1186 - 1187 - mutex_lock(&kvm->lock); 1188 - list_add(&stt->list, &kvm->arch.spapr_tce_tables); 1189 - 1190 - mutex_unlock(&kvm->lock); 1191 - 1192 - return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, 1193 - stt, O_RDWR); 1194 - 1195 - fail: 1196 - if (stt) { 1197 - for (i = 0; i < npages; i++) 1198 - if (stt->pages[i]) 1199 - __free_page(stt->pages[i]); 1200 - 1201 - kfree(stt); 1202 - } 1203 - return ret; 1204 - } 1205 1096 1206 1097 /* Work out RMLS (real mode limit selector) field value for a given RMA size. 1207 1098 Assumes POWER7 or PPC970. */
+7
arch/powerpc/kvm/book3s_pr.c
··· 1171 1171 1172 1172 int kvmppc_core_init_vm(struct kvm *kvm) 1173 1173 { 1174 + #ifdef CONFIG_PPC64 1175 + INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); 1176 + #endif 1177 + 1174 1178 return 0; 1175 1179 } 1176 1180 1177 1181 void kvmppc_core_destroy_vm(struct kvm *kvm) 1178 1182 { 1183 + #ifdef CONFIG_PPC64 1184 + WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables)); 1185 + #endif 1179 1186 } 1180 1187 1181 1188 static int kvmppc_book3s_init(void)
+18
arch/powerpc/kvm/book3s_pr_papr.c
··· 15 15 * published by the Free Software Foundation. 16 16 */ 17 17 18 + #include <linux/anon_inodes.h> 19 + 18 20 #include <asm/uaccess.h> 19 21 #include <asm/kvm_ppc.h> 20 22 #include <asm/kvm_book3s.h> ··· 213 211 return EMULATE_DONE; 214 212 } 215 213 214 + static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu) 215 + { 216 + unsigned long liobn = kvmppc_get_gpr(vcpu, 4); 217 + unsigned long ioba = kvmppc_get_gpr(vcpu, 5); 218 + unsigned long tce = kvmppc_get_gpr(vcpu, 6); 219 + long rc; 220 + 221 + rc = kvmppc_h_put_tce(vcpu, liobn, ioba, tce); 222 + if (rc == H_TOO_HARD) 223 + return EMULATE_FAIL; 224 + kvmppc_set_gpr(vcpu, 3, rc); 225 + return EMULATE_DONE; 226 + } 227 + 216 228 int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) 217 229 { 218 230 switch (cmd) { ··· 238 222 return kvmppc_h_pr_protect(vcpu); 239 223 case H_BULK_REMOVE: 240 224 return kvmppc_h_pr_bulk_remove(vcpu); 225 + case H_PUT_TCE: 226 + return kvmppc_h_pr_put_tce(vcpu); 241 227 case H_CEDE: 242 228 kvm_vcpu_block(vcpu); 243 229 clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
+6 -2
arch/powerpc/kvm/powerpc.c
··· 244 244 r = KVM_COALESCED_MMIO_PAGE_OFFSET; 245 245 break; 246 246 #endif 247 - #ifdef CONFIG_KVM_BOOK3S_64_HV 247 + #ifdef CONFIG_PPC_BOOK3S_64 248 248 case KVM_CAP_SPAPR_TCE: 249 249 r = 1; 250 250 break; 251 + #endif /* CONFIG_PPC_BOOK3S_64 */ 252 + #ifdef CONFIG_KVM_BOOK3S_64_HV 251 253 case KVM_CAP_PPC_SMT: 252 254 r = threads_per_core; 253 255 break; ··· 775 773 776 774 break; 777 775 } 778 - #ifdef CONFIG_KVM_BOOK3S_64_HV 776 + #ifdef CONFIG_PPC_BOOK3S_64 779 777 case KVM_CREATE_SPAPR_TCE: { 780 778 struct kvm_create_spapr_tce create_tce; 781 779 struct kvm *kvm = filp->private_data; ··· 786 784 r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce); 787 785 goto out; 788 786 } 787 + #endif /* CONFIG_PPC_BOOK3S_64 */ 789 788 789 + #ifdef CONFIG_KVM_BOOK3S_64_HV 790 790 case KVM_ALLOCATE_RMA: { 791 791 struct kvm *kvm = filp->private_data; 792 792 struct kvm_allocate_rma rma;