diff options
author | Hollis Blanchard <hollisb@us.ibm.com> | 2008-07-25 14:54:50 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-27 05:02:05 -0400 |
commit | cc04454fa81e93b5f1b5133950331639d2f59f85 (patch) | |
tree | adc2c214ccfc66dd097ec9c71f2995e65acc565a | |
parent | 5a00a5e7a3e013b2323f87c1b69ff9557eae5ec9 (diff) |
KVM: ppc: fix invalidation of large guest pages
When guest invalidates a large tlb map, there may be more than one
corresponding shadow tlb maps that need to be invalidated. Use eaddr and eend
to find these shadow tlb maps.
Signed-off-by: Liu Yu <yu.liu@freescale.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | arch/powerpc/kvm/44x_tlb.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kvm/emulate.c | 2 | ||||
-rw-r--r-- | include/asm-powerpc/kvm_ppc.h | 3 |
3 files changed, 6 insertions, 4 deletions
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 75dff7cfa814..5a5602da5091 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c | |||
@@ -177,7 +177,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, | |||
177 | vcpu->arch.msr & MSR_PR); | 177 | vcpu->arch.msr & MSR_PR); |
178 | } | 178 | } |
179 | 179 | ||
180 | void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid) | 180 | void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, |
181 | gva_t eend, u32 asid) | ||
181 | { | 182 | { |
182 | unsigned int pid = asid & 0xff; | 183 | unsigned int pid = asid & 0xff; |
183 | int i; | 184 | int i; |
@@ -191,7 +192,7 @@ void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid) | |||
191 | if (!get_tlb_v(stlbe)) | 192 | if (!get_tlb_v(stlbe)) |
192 | continue; | 193 | continue; |
193 | 194 | ||
194 | if (eaddr < get_tlb_eaddr(stlbe)) | 195 | if (eend < get_tlb_eaddr(stlbe)) |
195 | continue; | 196 | continue; |
196 | 197 | ||
197 | if (eaddr > get_tlb_end(stlbe)) | 198 | if (eaddr > get_tlb_end(stlbe)) |
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 000097461283..8c605d0a5488 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -137,7 +137,7 @@ static int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u32 inst) | |||
137 | if (tlbe->word0 & PPC44x_TLB_VALID) { | 137 | if (tlbe->word0 & PPC44x_TLB_VALID) { |
138 | eaddr = get_tlb_eaddr(tlbe); | 138 | eaddr = get_tlb_eaddr(tlbe); |
139 | asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid; | 139 | asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid; |
140 | kvmppc_mmu_invalidate(vcpu, eaddr, asid); | 140 | kvmppc_mmu_invalidate(vcpu, eaddr, get_tlb_end(tlbe), asid); |
141 | } | 141 | } |
142 | 142 | ||
143 | switch (ws) { | 143 | switch (ws) { |
diff --git a/include/asm-powerpc/kvm_ppc.h b/include/asm-powerpc/kvm_ppc.h index 5a21115228af..a8b068792260 100644 --- a/include/asm-powerpc/kvm_ppc.h +++ b/include/asm-powerpc/kvm_ppc.h | |||
@@ -61,7 +61,8 @@ extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); | |||
61 | 61 | ||
62 | extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, | 62 | extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, |
63 | u64 asid, u32 flags); | 63 | u64 asid, u32 flags); |
64 | extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid); | 64 | extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, |
65 | gva_t eend, u32 asid); | ||
65 | extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); | 66 | extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); |
66 | 67 | ||
67 | extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu); | 68 | extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu); |