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>
This commit is contained in:
parent
5a00a5e7a3
commit
cc04454fa8
@ -177,7 +177,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid,
|
|||||||
vcpu->arch.msr & MSR_PR);
|
vcpu->arch.msr & MSR_PR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid)
|
void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
|
||||||
|
gva_t eend, u32 asid)
|
||||||
{
|
{
|
||||||
unsigned int pid = asid & 0xff;
|
unsigned int pid = asid & 0xff;
|
||||||
int i;
|
int i;
|
||||||
@ -191,7 +192,7 @@ void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid)
|
|||||||
if (!get_tlb_v(stlbe))
|
if (!get_tlb_v(stlbe))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (eaddr < get_tlb_eaddr(stlbe))
|
if (eend < get_tlb_eaddr(stlbe))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (eaddr > get_tlb_end(stlbe))
|
if (eaddr > get_tlb_end(stlbe))
|
||||||
|
@ -137,7 +137,7 @@ static int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u32 inst)
|
|||||||
if (tlbe->word0 & PPC44x_TLB_VALID) {
|
if (tlbe->word0 & PPC44x_TLB_VALID) {
|
||||||
eaddr = get_tlb_eaddr(tlbe);
|
eaddr = get_tlb_eaddr(tlbe);
|
||||||
asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid;
|
asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid;
|
||||||
kvmppc_mmu_invalidate(vcpu, eaddr, asid);
|
kvmppc_mmu_invalidate(vcpu, eaddr, get_tlb_end(tlbe), asid);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ws) {
|
switch (ws) {
|
||||||
|
@ -61,7 +61,8 @@ extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
|||||||
|
|
||||||
extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn,
|
extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn,
|
||||||
u64 asid, u32 flags);
|
u64 asid, u32 flags);
|
||||||
extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid);
|
extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
|
||||||
|
gva_t eend, u32 asid);
|
||||||
extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
|
extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
|
||||||
|
|
||||||
extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu);
|
extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu);
|
||||||
|
Loading…
Reference in New Issue
Block a user