diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2016-01-29 10:01:28 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2016-02-29 13:34:15 -0500 |
commit | 57c841f131ef295b583365d2fddd6b0d16e82c10 (patch) | |
tree | e015fcf1eccbcc2d01f87762cddb29738e1a3bf8 /arch/arm/kvm | |
parent | 402f352876ba0df574533e59d72fc3e9871f791a (diff) |
arm/arm64: KVM: Handle out-of-RAM cache maintenance as a NOP
So far, our handling of cache maintenance by VA has been pretty
simple: Either the access is in the guest RAM and generates a S2
fault, which results in the page being mapped RW, or we go down
the io_mem_abort() path, and nuke the guest.
The first one is fine, but the second one is extremely weird.
Treating the CM as an I/O is wrong, and nothing in the ARM ARM
indicates that we should generate a fault for something that
cannot end-up in the cache anyway (even if the guest maps it,
it will keep on faulting at stage-2 for emulation).
So let's just skip this instruction, and let the guest get away
with it.
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r-- | arch/arm/kvm/mmu.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index aba61fd3697a..c3eb10ea0971 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -1431,6 +1431,22 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | /* | 1433 | /* |
1434 | * Check for a cache maintenance operation. Since we | ||
1435 | * ended-up here, we know it is outside of any memory | ||
1436 | * slot. But we can't find out if that is for a device, | ||
1437 | * or if the guest is just being stupid. The only thing | ||
1438 | * we know for sure is that this range cannot be cached. | ||
1439 | * | ||
1440 | * So let's assume that the guest is just being | ||
1441 | * cautious, and skip the instruction. | ||
1442 | */ | ||
1443 | if (kvm_vcpu_dabt_is_cm(vcpu)) { | ||
1444 | kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); | ||
1445 | ret = 1; | ||
1446 | goto out_unlock; | ||
1447 | } | ||
1448 | |||
1449 | /* | ||
1434 | * The IPA is reported as [MAX:12], so we need to | 1450 | * The IPA is reported as [MAX:12], so we need to |
1435 | * complement it with the bottom 12 bits from the | 1451 | * complement it with the bottom 12 bits from the |
1436 | * faulting VA. This is always 12 bits, irrespective | 1452 | * faulting VA. This is always 12 bits, irrespective |