diff options
author | James Hogan <james.hogan@imgtec.com> | 2016-08-19 10:09:47 -0400 |
---|---|---|
committer | James Hogan <james.hogan@imgtec.com> | 2016-09-08 13:29:54 -0400 |
commit | d5888477d31c64dba9264fbb33cfa9b066f071d0 (patch) | |
tree | fdc2e5eb025f4f977b78f78ef4e76e786781886d | |
parent | f6f7017192ad62669dc8aa4cb33e5f5a0ecd2d81 (diff) |
KVM: MIPS: Emulate MMIO via TLB miss for EVA
MIPS Enhanced Virtual Addressing (EVA) allows the virtual memory
segments to be rearranged such that the KSeg0/KSeg1 segments are
accessible TLB mapped to user mode, which would trigger a TLB Miss
exception (due to lack of TLB mappings) instead of an Address Error
exception.
Update the TLB Miss handling similar to Address Error handling for guest
MMIO emulation.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Radim Krčmář" <rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
Cc: kvm@vger.kernel.org
-rw-r--r-- | arch/mips/kvm/trap_emul.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index 091553942bcb..3a5484f9aa50 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c | |||
@@ -175,6 +175,24 @@ static int kvm_trap_emul_handle_tlb_miss(struct kvm_vcpu *vcpu, bool store) | |||
175 | run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | 175 | run->exit_reason = KVM_EXIT_INTERNAL_ERROR; |
176 | ret = RESUME_HOST; | 176 | ret = RESUME_HOST; |
177 | } | 177 | } |
178 | } else if (KVM_GUEST_KERNEL_MODE(vcpu) | ||
179 | && (KSEGX(badvaddr) == CKSEG0 || KSEGX(badvaddr) == CKSEG1)) { | ||
180 | /* | ||
181 | * With EVA we may get a TLB exception instead of an address | ||
182 | * error when the guest performs MMIO to KSeg1 addresses. | ||
183 | */ | ||
184 | kvm_debug("Emulate %s MMIO space\n", | ||
185 | store ? "Store to" : "Load from"); | ||
186 | er = kvm_mips_emulate_inst(cause, opc, run, vcpu); | ||
187 | if (er == EMULATE_FAIL) { | ||
188 | kvm_err("Emulate %s MMIO space failed\n", | ||
189 | store ? "Store to" : "Load from"); | ||
190 | run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
191 | ret = RESUME_HOST; | ||
192 | } else { | ||
193 | run->exit_reason = KVM_EXIT_MMIO; | ||
194 | ret = RESUME_HOST; | ||
195 | } | ||
178 | } else { | 196 | } else { |
179 | kvm_err("Illegal TLB %s fault address , cause %#x, PC: %p, BadVaddr: %#lx\n", | 197 | kvm_err("Illegal TLB %s fault address , cause %#x, PC: %p, BadVaddr: %#lx\n", |
180 | store ? "ST" : "LD", cause, opc, badvaddr); | 198 | store ? "ST" : "LD", cause, opc, badvaddr); |