^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2012 - Virtual Open Systems and Columbia University
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Christoffer Dall <c.dall@virtualopensystems.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kvm_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/kvm_emulate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <trace/events/kvm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) void *datap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) u8 byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) u16 hword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) u32 word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) u64 dword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) } tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) tmp.byte = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) datap = &tmp.byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) tmp.hword = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) datap = &tmp.hword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) tmp.word = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) datap = &tmp.word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) tmp.dword = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) datap = &tmp.dword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) memcpy(buf, datap, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned long data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u16 hword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u32 word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u64 dword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) } tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) data = *(u8 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) memcpy(&tmp.hword, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) data = tmp.hword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) memcpy(&tmp.word, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) data = tmp.word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) memcpy(&tmp.dword, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) data = tmp.dword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * or in-kernel IO emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * @vcpu: The VCPU pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int kvm_handle_mmio_return(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Detect an already handled MMIO return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (unlikely(!vcpu->mmio_needed))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) vcpu->mmio_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (!kvm_vcpu_dabt_iswrite(vcpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct kvm_run *run = vcpu->run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) len = kvm_vcpu_dabt_get_as(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) data = kvm_mmio_read_buf(run->mmio.data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (kvm_vcpu_dabt_issext(vcpu) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) len < sizeof(unsigned long)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) mask = 1U << ((len * 8) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) data = (data ^ mask) - mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!kvm_vcpu_dabt_issf(vcpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) data = data & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) data = vcpu_data_host_to_guest(vcpu, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * The MMIO instruction is emulated and should not be re-executed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * in the guest.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) kvm_incr_pc(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct kvm_run *run = vcpu->run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned long data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned long rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) bool is_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u8 data_buf[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * No valid syndrome? Ask userspace for help if it has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * volunteered to do so, and bail out otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (!kvm_vcpu_dabt_isvalid(vcpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (vcpu->kvm->arch.return_nisv_io_abort_to_user) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) run->exit_reason = KVM_EXIT_ARM_NISV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) run->arm_nisv.esr_iss = kvm_vcpu_dabt_iss_nisv_sanitized(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) run->arm_nisv.fault_ipa = fault_ipa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) kvm_pr_unimpl("Data abort outside memslots with no valid syndrome info\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * Prepare MMIO operation. First decode the syndrome data we get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * from the CPU. Then try if some in-kernel emulation feels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * responsible, otherwise let user space do its magic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) is_write = kvm_vcpu_dabt_iswrite(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) len = kvm_vcpu_dabt_get_as(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) rt = kvm_vcpu_dabt_get_rd(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) kvm_mmio_write_buf(data_buf, len, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) data_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) fault_ipa, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) data_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Now prepare kvm_run for the potential return to userland. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) run->mmio.is_write = is_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) run->mmio.phys_addr = fault_ipa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) run->mmio.len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) vcpu->mmio_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* We handled the access successfully in the kernel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (!is_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) memcpy(run->mmio.data, data_buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) vcpu->stat.mmio_exit_kernel++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) kvm_handle_mmio_return(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (is_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) memcpy(run->mmio.data, data_buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) vcpu->stat.mmio_exit_user++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) run->exit_reason = KVM_EXIT_MMIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }