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

KVM: PPC: e500: Add shadow PID support

Dynamically assign host PIDs to guest PIDs, splitting each guest PID into
multiple host (shadow) PIDs based on kernel/user and MSR[IS/DS]. Use
both PID0 and PID1 so that the shadow PIDs for the right mode can be
selected, that correspond both to guest TID = zero and guest TID = guest
PID.

This allows us to significantly reduce the frequency of needing to
invalidate the entire TLB. When the guest mode or PID changes, we just
update the host PID0/PID1. And since the allocation of shadow PIDs is
global, multiple guests can share the TLB without conflict.

Note that KVM does not yet support the guest setting PID1 or PID2 to
a value other than zero. This will need to be fixed for nested KVM
to work. Until then, we enforce the requirement for guest PID1/PID2
to stay zero by failing the emulation if the guest tries to set them
to something else.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>

authored by

Liu Yu and committed by
Avi Kivity
dd9ebf1f 08b7fa92

+334 -32
+7 -1
arch/powerpc/include/asm/kvm_e500.h
··· 1 1 /* 2 - * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. 2 + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved. 3 3 * 4 4 * Author: Yu Liu, <yu.liu@freescale.com> 5 5 * ··· 37 37 unsigned int flags; /* E500_TLB_* */ 38 38 }; 39 39 40 + struct vcpu_id_table; 41 + 40 42 struct kvmppc_vcpu_e500 { 41 43 /* Unmodified copy of the guest's TLB. */ 42 44 struct tlbe *gtlb_arch[E500_TLB_NUM]; ··· 61 59 u32 mas5; 62 60 u32 mas6; 63 61 u32 mas7; 62 + 63 + /* vcpu id table */ 64 + struct vcpu_id_table *idt; 65 + 64 66 u32 l1csr0; 65 67 u32 l1csr1; 66 68 u32 hid0;
+1
arch/powerpc/include/asm/kvm_host.h
··· 255 255 u32 pvr; 256 256 257 257 u32 shadow_pid; 258 + u32 shadow_pid1; 258 259 u32 pid; 259 260 u32 swap_pid; 260 261
+1
arch/powerpc/kernel/asm-offsets.c
··· 402 402 DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6)); 403 403 DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7)); 404 404 DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid)); 405 + DEFINE(VCPU_SHADOW_PID1, offsetof(struct kvm_vcpu, arch.shadow_pid1)); 405 406 DEFINE(VCPU_SHARED, offsetof(struct kvm_vcpu, arch.shared)); 406 407 DEFINE(VCPU_SHARED_MSR, offsetof(struct kvm_vcpu_arch_shared, msr)); 407 408 DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr));
+3 -1
arch/powerpc/kvm/44x_tlb.c
··· 387 387 } 388 388 } 389 389 390 - void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode) 390 + void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) 391 391 { 392 + int usermode = vcpu->arch.shared->msr & MSR_PR; 393 + 392 394 vcpu->arch.shadow_pid = !usermode; 393 395 } 394 396
+7 -4
arch/powerpc/kvm/booke.c
··· 113 113 } 114 114 #endif 115 115 116 - /* Helper function for "full" MSR writes. No need to call this if only EE is 117 - * changing. */ 116 + /* 117 + * Helper function for "full" MSR writes. No need to call this if only 118 + * EE/CE/ME/DE/RI are changing. 119 + */ 118 120 void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr) 119 121 { 120 - if ((new_msr & MSR_PR) != (vcpu->arch.shared->msr & MSR_PR)) 121 - kvmppc_mmu_priv_switch(vcpu, new_msr & MSR_PR); 122 + u32 old_msr = vcpu->arch.shared->msr; 122 123 123 124 vcpu->arch.shared->msr = new_msr; 125 + 126 + kvmppc_mmu_msr_notify(vcpu, old_msr); 124 127 125 128 if (vcpu->arch.shared->msr & MSR_WE) { 126 129 kvm_vcpu_block(vcpu);
+1
arch/powerpc/kvm/booke.h
··· 53 53 extern unsigned long kvmppc_booke_handlers; 54 54 55 55 void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr); 56 + void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr); 56 57 57 58 int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, 58 59 unsigned int inst, int *advance);
+11
arch/powerpc/kvm/booke_interrupts.S
··· 191 191 lwz r3, VCPU_HOST_PID(r4) 192 192 mtspr SPRN_PID, r3 193 193 194 + #ifdef CONFIG_FSL_BOOKE 195 + /* we cheat and know that Linux doesn't use PID1 which is always 0 */ 196 + lis r3, 0 197 + mtspr SPRN_PID1, r3 198 + #endif 199 + 194 200 /* Restore host IVPR before re-enabling interrupts. We cheat and know 195 201 * that Linux IVPR is always 0xc0000000. */ 196 202 lis r3, 0xc000 ··· 370 364 stw r3, VCPU_HOST_PID(r4) 371 365 lwz r3, VCPU_SHADOW_PID(r4) 372 366 mtspr SPRN_PID, r3 367 + 368 + #ifdef CONFIG_FSL_BOOKE 369 + lwz r3, VCPU_SHADOW_PID1(r4) 370 + mtspr SPRN_PID1, r3 371 + #endif 373 372 374 373 #ifdef CONFIG_44x 375 374 iccci 0, 0 /* XXX hack */
+4
arch/powerpc/kvm/e500_emulate.c
··· 81 81 kvmppc_set_pid(vcpu, spr_val); 82 82 break; 83 83 case SPRN_PID1: 84 + if (spr_val != 0) 85 + return EMULATE_FAIL; 84 86 vcpu_e500->pid[1] = spr_val; break; 85 87 case SPRN_PID2: 88 + if (spr_val != 0) 89 + return EMULATE_FAIL; 86 90 vcpu_e500->pid[2] = spr_val; break; 87 91 case SPRN_MAS0: 88 92 vcpu_e500->mas0 = spr_val; break;
+287 -25
arch/powerpc/kvm/e500_tlb.c
··· 28 28 29 29 #define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1) 30 30 31 + struct id { 32 + unsigned long val; 33 + struct id **pentry; 34 + }; 35 + 36 + #define NUM_TIDS 256 37 + 38 + /* 39 + * This table provide mappings from: 40 + * (guestAS,guestTID,guestPR) --> ID of physical cpu 41 + * guestAS [0..1] 42 + * guestTID [0..255] 43 + * guestPR [0..1] 44 + * ID [1..255] 45 + * Each vcpu keeps one vcpu_id_table. 46 + */ 47 + struct vcpu_id_table { 48 + struct id id[2][NUM_TIDS][2]; 49 + }; 50 + 51 + /* 52 + * This table provide reversed mappings of vcpu_id_table: 53 + * ID --> address of vcpu_id_table item. 54 + * Each physical core has one pcpu_id_table. 55 + */ 56 + struct pcpu_id_table { 57 + struct id *entry[NUM_TIDS]; 58 + }; 59 + 60 + static DEFINE_PER_CPU(struct pcpu_id_table, pcpu_sids); 61 + 62 + /* This variable keeps last used shadow ID on local core. 63 + * The valid range of shadow ID is [1..255] */ 64 + static DEFINE_PER_CPU(unsigned long, pcpu_last_used_sid); 65 + 31 66 static unsigned int tlb1_entry_num; 67 + 68 + /* 69 + * Allocate a free shadow id and setup a valid sid mapping in given entry. 70 + * A mapping is only valid when vcpu_id_table and pcpu_id_table are match. 71 + * 72 + * The caller must have preemption disabled, and keep it that way until 73 + * it has finished with the returned shadow id (either written into the 74 + * TLB or arch.shadow_pid, or discarded). 75 + */ 76 + static inline int local_sid_setup_one(struct id *entry) 77 + { 78 + unsigned long sid; 79 + int ret = -1; 80 + 81 + sid = ++(__get_cpu_var(pcpu_last_used_sid)); 82 + if (sid < NUM_TIDS) { 83 + __get_cpu_var(pcpu_sids).entry[sid] = entry; 84 + entry->val = sid; 85 + entry->pentry = &__get_cpu_var(pcpu_sids).entry[sid]; 86 + ret = sid; 87 + } 88 + 89 + /* 90 + * If sid == NUM_TIDS, we've run out of sids. We return -1, and 91 + * the caller will invalidate everything and start over. 92 + * 93 + * sid > NUM_TIDS indicates a race, which we disable preemption to 94 + * avoid. 95 + */ 96 + WARN_ON(sid > NUM_TIDS); 97 + 98 + return ret; 99 + } 100 + 101 + /* 102 + * Check if given entry contain a valid shadow id mapping. 103 + * An ID mapping is considered valid only if 104 + * both vcpu and pcpu know this mapping. 105 + * 106 + * The caller must have preemption disabled, and keep it that way until 107 + * it has finished with the returned shadow id (either written into the 108 + * TLB or arch.shadow_pid, or discarded). 109 + */ 110 + static inline int local_sid_lookup(struct id *entry) 111 + { 112 + if (entry && entry->val != 0 && 113 + __get_cpu_var(pcpu_sids).entry[entry->val] == entry && 114 + entry->pentry == &__get_cpu_var(pcpu_sids).entry[entry->val]) 115 + return entry->val; 116 + return -1; 117 + } 118 + 119 + /* Invalidate all id mappings on local core */ 120 + static inline void local_sid_destroy_all(void) 121 + { 122 + preempt_disable(); 123 + __get_cpu_var(pcpu_last_used_sid) = 0; 124 + memset(&__get_cpu_var(pcpu_sids), 0, sizeof(__get_cpu_var(pcpu_sids))); 125 + preempt_enable(); 126 + } 127 + 128 + static void *kvmppc_e500_id_table_alloc(struct kvmppc_vcpu_e500 *vcpu_e500) 129 + { 130 + vcpu_e500->idt = kzalloc(sizeof(struct vcpu_id_table), GFP_KERNEL); 131 + return vcpu_e500->idt; 132 + } 133 + 134 + static void kvmppc_e500_id_table_free(struct kvmppc_vcpu_e500 *vcpu_e500) 135 + { 136 + kfree(vcpu_e500->idt); 137 + } 138 + 139 + /* Invalidate all mappings on vcpu */ 140 + static void kvmppc_e500_id_table_reset_all(struct kvmppc_vcpu_e500 *vcpu_e500) 141 + { 142 + memset(vcpu_e500->idt, 0, sizeof(struct vcpu_id_table)); 143 + 144 + /* Update shadow pid when mappings are changed */ 145 + kvmppc_e500_recalc_shadow_pid(vcpu_e500); 146 + } 147 + 148 + /* Invalidate one ID mapping on vcpu */ 149 + static inline void kvmppc_e500_id_table_reset_one( 150 + struct kvmppc_vcpu_e500 *vcpu_e500, 151 + int as, int pid, int pr) 152 + { 153 + struct vcpu_id_table *idt = vcpu_e500->idt; 154 + 155 + BUG_ON(as >= 2); 156 + BUG_ON(pid >= NUM_TIDS); 157 + BUG_ON(pr >= 2); 158 + 159 + idt->id[as][pid][pr].val = 0; 160 + idt->id[as][pid][pr].pentry = NULL; 161 + 162 + /* Update shadow pid when mappings are changed */ 163 + kvmppc_e500_recalc_shadow_pid(vcpu_e500); 164 + } 165 + 166 + /* 167 + * Map guest (vcpu,AS,ID,PR) to physical core shadow id. 168 + * This function first lookup if a valid mapping exists, 169 + * if not, then creates a new one. 170 + * 171 + * The caller must have preemption disabled, and keep it that way until 172 + * it has finished with the returned shadow id (either written into the 173 + * TLB or arch.shadow_pid, or discarded). 174 + */ 175 + static unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500, 176 + unsigned int as, unsigned int gid, 177 + unsigned int pr, int avoid_recursion) 178 + { 179 + struct vcpu_id_table *idt = vcpu_e500->idt; 180 + int sid; 181 + 182 + BUG_ON(as >= 2); 183 + BUG_ON(gid >= NUM_TIDS); 184 + BUG_ON(pr >= 2); 185 + 186 + sid = local_sid_lookup(&idt->id[as][gid][pr]); 187 + 188 + while (sid <= 0) { 189 + /* No mapping yet */ 190 + sid = local_sid_setup_one(&idt->id[as][gid][pr]); 191 + if (sid <= 0) { 192 + _tlbil_all(); 193 + local_sid_destroy_all(); 194 + } 195 + 196 + /* Update shadow pid when mappings are changed */ 197 + if (!avoid_recursion) 198 + kvmppc_e500_recalc_shadow_pid(vcpu_e500); 199 + } 200 + 201 + return sid; 202 + } 203 + 204 + /* Map guest pid to shadow. 205 + * We use PID to keep shadow of current guest non-zero PID, 206 + * and use PID1 to keep shadow of guest zero PID. 207 + * So that guest tlbe with TID=0 can be accessed at any time */ 208 + void kvmppc_e500_recalc_shadow_pid(struct kvmppc_vcpu_e500 *vcpu_e500) 209 + { 210 + preempt_disable(); 211 + vcpu_e500->vcpu.arch.shadow_pid = kvmppc_e500_get_sid(vcpu_e500, 212 + get_cur_as(&vcpu_e500->vcpu), 213 + get_cur_pid(&vcpu_e500->vcpu), 214 + get_cur_pr(&vcpu_e500->vcpu), 1); 215 + vcpu_e500->vcpu.arch.shadow_pid1 = kvmppc_e500_get_sid(vcpu_e500, 216 + get_cur_as(&vcpu_e500->vcpu), 0, 217 + get_cur_pr(&vcpu_e500->vcpu), 1); 218 + preempt_enable(); 219 + } 32 220 33 221 void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu) 34 222 { ··· 322 134 323 135 void kvmppc_map_magic(struct kvm_vcpu *vcpu) 324 136 { 137 + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 325 138 struct tlbe magic; 326 139 ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK; 140 + unsigned int stid; 327 141 pfn_t pfn; 328 142 329 143 pfn = (pfn_t)virt_to_phys((void *)shared_page) >> PAGE_SHIFT; 330 144 get_page(pfn_to_page(pfn)); 331 145 332 - magic.mas1 = MAS1_VALID | MAS1_TS | 146 + preempt_disable(); 147 + stid = kvmppc_e500_get_sid(vcpu_e500, 0, 0, 0, 0); 148 + 149 + magic.mas1 = MAS1_VALID | MAS1_TS | MAS1_TID(stid) | 333 150 MAS1_TSIZE(BOOK3E_PAGESZ_4K); 334 151 magic.mas2 = vcpu->arch.magic_page_ea | MAS2_M; 335 152 magic.mas3 = (pfn << PAGE_SHIFT) | ··· 342 149 magic.mas7 = pfn >> (32 - PAGE_SHIFT); 343 150 344 151 __write_host_tlbe(&magic, MAS0_TLBSEL(1) | MAS0_ESEL(tlbcam_index)); 152 + preempt_enable(); 345 153 } 346 154 347 155 void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu) 348 156 { 157 + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 158 + 159 + /* Shadow PID may be expired on local core */ 160 + kvmppc_e500_recalc_shadow_pid(vcpu_e500); 349 161 } 350 162 351 163 void kvmppc_e500_tlb_put(struct kvm_vcpu *vcpu) 352 164 { 353 - _tlbil_all(); 165 + } 166 + 167 + static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, 168 + int tlbsel, int esel) 169 + { 170 + struct tlbe *gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel]; 171 + struct vcpu_id_table *idt = vcpu_e500->idt; 172 + unsigned int pr, tid, ts, pid; 173 + u32 val, eaddr; 174 + unsigned long flags; 175 + 176 + ts = get_tlb_ts(gtlbe); 177 + tid = get_tlb_tid(gtlbe); 178 + 179 + preempt_disable(); 180 + 181 + /* One guest ID may be mapped to two shadow IDs */ 182 + for (pr = 0; pr < 2; pr++) { 183 + /* 184 + * The shadow PID can have a valid mapping on at most one 185 + * host CPU. In the common case, it will be valid on this 186 + * CPU, in which case (for TLB0) we do a local invalidation 187 + * of the specific address. 188 + * 189 + * If the shadow PID is not valid on the current host CPU, or 190 + * if we're invalidating a TLB1 entry, we invalidate the 191 + * entire shadow PID. 192 + */ 193 + if (tlbsel == 1 || 194 + (pid = local_sid_lookup(&idt->id[ts][tid][pr])) <= 0) { 195 + kvmppc_e500_id_table_reset_one(vcpu_e500, ts, tid, pr); 196 + continue; 197 + } 198 + 199 + /* 200 + * The guest is invalidating a TLB0 entry which is in a PID 201 + * that has a valid shadow mapping on this host CPU. We 202 + * search host TLB0 to invalidate it's shadow TLB entry, 203 + * similar to __tlbil_va except that we need to look in AS1. 204 + */ 205 + val = (pid << MAS6_SPID_SHIFT) | MAS6_SAS; 206 + eaddr = get_tlb_eaddr(gtlbe); 207 + 208 + local_irq_save(flags); 209 + 210 + mtspr(SPRN_MAS6, val); 211 + asm volatile("tlbsx 0, %[eaddr]" : : [eaddr] "r" (eaddr)); 212 + val = mfspr(SPRN_MAS1); 213 + if (val & MAS1_VALID) { 214 + mtspr(SPRN_MAS1, val & ~MAS1_VALID); 215 + asm volatile("tlbwe"); 216 + } 217 + 218 + local_irq_restore(flags); 219 + } 220 + 221 + preempt_enable(); 354 222 } 355 223 356 224 /* Search the guest TLB for a matching entry. */ ··· 470 216 } 471 217 } 472 218 473 - static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, 474 - int esel) 475 - { 476 - mtspr(SPRN_MMUCSR0, MMUCSR0_TLB1FI); 477 - } 478 - 479 219 static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu, 480 220 unsigned int eaddr, int as) 481 221 { ··· 503 255 u64 gvaddr, struct tlbe *stlbe) 504 256 { 505 257 pfn_t pfn = priv->pfn; 258 + unsigned int stid; 259 + 260 + stid = kvmppc_e500_get_sid(vcpu_e500, get_tlb_ts(gtlbe), 261 + get_tlb_tid(gtlbe), 262 + get_cur_pr(&vcpu_e500->vcpu), 0); 506 263 507 264 /* Force TS=1 IPROT=0 for all guest mappings. */ 508 265 stlbe->mas1 = MAS1_TSIZE(tsize) 509 - | MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID; 266 + | MAS1_TID(stid) | MAS1_TS | MAS1_VALID; 510 267 stlbe->mas2 = (gvaddr & MAS2_EPN) 511 268 | e500_shadow_mas2_attrib(gtlbe->mas2, 512 269 vcpu_e500->vcpu.arch.shared->msr & MSR_PR); ··· 667 414 return victim; 668 415 } 669 416 670 - /* Invalidate all guest kernel mappings when enter usermode, 671 - * so that when they fault back in they will get the 672 - * proper permission bits. */ 673 - void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode) 417 + void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) 674 418 { 675 - if (usermode) { 676 - _tlbil_all(); 677 - } 419 + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 420 + 421 + /* Recalc shadow pid since MSR changes */ 422 + kvmppc_e500_recalc_shadow_pid(vcpu_e500); 678 423 } 679 424 680 425 static inline int kvmppc_e500_gtlbe_invalidate( ··· 700 449 for (esel = 0; esel < vcpu_e500->gtlb_size[1]; esel++) 701 450 kvmppc_e500_gtlbe_invalidate(vcpu_e500, 1, esel); 702 451 703 - _tlbil_all(); 452 + /* Invalidate all vcpu id mappings */ 453 + kvmppc_e500_id_table_reset_all(vcpu_e500); 704 454 705 455 return EMULATE_DONE; 706 456 } ··· 732 480 kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel); 733 481 } 734 482 735 - _tlbil_all(); 483 + /* Invalidate all vcpu id mappings */ 484 + kvmppc_e500_id_table_reset_all(vcpu_e500); 736 485 737 486 return EMULATE_DONE; 738 487 } ··· 817 564 818 565 gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel]; 819 566 820 - if (get_tlb_v(gtlbe) && tlbsel == 1) 821 - kvmppc_e500_tlb1_invalidate(vcpu_e500, esel); 567 + if (get_tlb_v(gtlbe)) 568 + kvmppc_e500_stlbe_invalidate(vcpu_e500, tlbsel, esel); 822 569 823 570 gtlbe->mas1 = vcpu_e500->mas1; 824 571 gtlbe->mas2 = vcpu_e500->mas2; ··· 835 582 u64 eaddr; 836 583 u64 raddr; 837 584 585 + preempt_disable(); 838 586 switch (tlbsel) { 839 587 case 0: 840 588 /* TLB0 */ ··· 865 611 BUG(); 866 612 } 867 613 write_host_tlbe(vcpu_e500, stlbsel, sesel, &stlbe); 614 + preempt_enable(); 868 615 } 869 616 870 617 kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); ··· 927 672 928 673 gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel]; 929 674 675 + preempt_disable(); 930 676 switch (tlbsel) { 931 677 case 0: 932 678 stlbsel = 0; ··· 953 697 } 954 698 955 699 write_host_tlbe(vcpu_e500, stlbsel, sesel, &stlbe); 700 + preempt_enable(); 956 701 } 957 702 958 703 int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu, ··· 975 718 { 976 719 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 977 720 978 - vcpu_e500->pid[0] = vcpu->arch.shadow_pid = 979 - vcpu->arch.pid = pid; 721 + if (vcpu->arch.pid != pid) { 722 + vcpu_e500->pid[0] = vcpu->arch.pid = pid; 723 + kvmppc_e500_recalc_shadow_pid(vcpu_e500); 724 + } 980 725 } 981 726 982 727 void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500) ··· 1026 767 if (vcpu_e500->gtlb_priv[1] == NULL) 1027 768 goto err_out_priv0; 1028 769 770 + if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL) 771 + goto err_out_priv1; 772 + 1029 773 /* Init TLB configuration register */ 1030 774 vcpu_e500->tlb0cfg = mfspr(SPRN_TLB0CFG) & ~0xfffUL; 1031 775 vcpu_e500->tlb0cfg |= vcpu_e500->gtlb_size[0]; ··· 1037 775 1038 776 return 0; 1039 777 778 + err_out_priv1: 779 + kfree(vcpu_e500->gtlb_priv[1]); 1040 780 err_out_priv0: 1041 781 kfree(vcpu_e500->gtlb_priv[0]); 1042 782 err_out_guest1: ··· 1061 797 kvmppc_e500_priv_release(priv); 1062 798 } 1063 799 1064 - /* discard all guest mapping */ 1065 - _tlbil_all(); 1066 - 800 + kvmppc_e500_id_table_free(vcpu_e500); 1067 801 kfree(vcpu_e500->gtlb_arch[1]); 1068 802 kfree(vcpu_e500->gtlb_arch[0]); 1069 803 }
+12 -1
arch/powerpc/kvm/e500_tlb.h
··· 1 1 /* 2 - * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. 2 + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved. 3 3 * 4 4 * Author: Yu Liu, yu.liu@freescale.com 5 5 * ··· 55 55 extern int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *); 56 56 extern void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *); 57 57 extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *); 58 + extern void kvmppc_e500_recalc_shadow_pid(struct kvmppc_vcpu_e500 *); 58 59 59 60 /* TLB helper functions */ 60 61 static inline unsigned int get_tlb_size(const struct tlbe *tlbe) ··· 109 108 static inline unsigned int get_cur_pid(struct kvm_vcpu *vcpu) 110 109 { 111 110 return vcpu->arch.pid & 0xff; 111 + } 112 + 113 + static inline unsigned int get_cur_as(struct kvm_vcpu *vcpu) 114 + { 115 + return !!(vcpu->arch.shared->msr & (MSR_IS | MSR_DS)); 116 + } 117 + 118 + static inline unsigned int get_cur_pr(struct kvm_vcpu *vcpu) 119 + { 120 + return !!(vcpu->arch.shared->msr & MSR_PR); 112 121 } 113 122 114 123 static inline unsigned int get_cur_spid(