1/* 2 * Copyright (C) 2012 - Virtual Open Systems and Columbia University 3 * Author: Christoffer Dall <c.dall@virtualopensystems.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License, version 2, as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19#include <linux/kvm_host.h> 20#include <asm/kvm_mmio.h> 21#include <asm/kvm_emulate.h> 22#include <trace/events/kvm.h> 23 24#include "trace.h" 25 26static void mmio_write_buf(char *buf, unsigned int len, unsigned long data) 27{ 28 void *datap = NULL; 29 union { 30 u8 byte; 31 u16 hword; 32 u32 word; 33 u64 dword; 34 } tmp; 35 36 switch (len) { 37 case 1: 38 tmp.byte = data; 39 datap = &tmp.byte; 40 break; 41 case 2: 42 tmp.hword = data; 43 datap = &tmp.hword; 44 break; 45 case 4: 46 tmp.word = data; 47 datap = &tmp.word; 48 break; 49 case 8: 50 tmp.dword = data; 51 datap = &tmp.dword; 52 break; 53 } 54 55 memcpy(buf, datap, len); 56} 57 58static unsigned long mmio_read_buf(char *buf, unsigned int len) 59{ 60 unsigned long data = 0; 61 union { 62 u16 hword; 63 u32 word; 64 u64 dword; 65 } tmp; 66 67 switch (len) { 68 case 1: 69 data = buf[0]; 70 break; 71 case 2: 72 memcpy(&tmp.hword, buf, len); 73 data = tmp.hword; 74 break; 75 case 4: 76 memcpy(&tmp.word, buf, len); 77 data = tmp.word; 78 break; 79 case 8: 80 memcpy(&tmp.dword, buf, len); 81 data = tmp.dword; 82 break; 83 } 84 85 return data; 86} 87 88/** 89 * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation 90 * @vcpu: The VCPU pointer 91 * @run: The VCPU run struct containing the mmio data 92 * 93 * This should only be called after returning from userspace for MMIO load 94 * emulation. 95 */ 96int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) 97{ 98 unsigned long data; 99 unsigned int len; 100 int mask; 101 102 if (!run->mmio.is_write) { 103 len = run->mmio.len; 104 if (len > sizeof(unsigned long)) 105 return -EINVAL; 106 107 data = mmio_read_buf(run->mmio.data, len); 108 109 if (vcpu->arch.mmio_decode.sign_extend && 110 len < sizeof(unsigned long)) { 111 mask = 1U << ((len * 8) - 1); 112 data = (data ^ mask) - mask; 113 } 114 115 trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr, 116 data); 117 data = vcpu_data_host_to_guest(vcpu, data, len); 118 *vcpu_reg(vcpu, vcpu->arch.mmio_decode.rt) = data; 119 } 120 121 return 0; 122} 123 124static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, 125 struct kvm_exit_mmio *mmio) 126{ 127 unsigned long rt; 128 int len; 129 bool is_write, sign_extend; 130 131 if (kvm_vcpu_dabt_isextabt(vcpu)) { 132 /* cache operation on I/O addr, tell guest unsupported */ 133 kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu)); 134 return 1; 135 } 136 137 if (kvm_vcpu_dabt_iss1tw(vcpu)) { 138 /* page table accesses IO mem: tell guest to fix its TTBR */ 139 kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu)); 140 return 1; 141 } 142 143 len = kvm_vcpu_dabt_get_as(vcpu); 144 if (unlikely(len < 0)) 145 return len; 146 147 is_write = kvm_vcpu_dabt_iswrite(vcpu); 148 sign_extend = kvm_vcpu_dabt_issext(vcpu); 149 rt = kvm_vcpu_dabt_get_rd(vcpu); 150 151 mmio->is_write = is_write; 152 mmio->phys_addr = fault_ipa; 153 mmio->len = len; 154 vcpu->arch.mmio_decode.sign_extend = sign_extend; 155 vcpu->arch.mmio_decode.rt = rt; 156 157 /* 158 * The MMIO instruction is emulated and should not be re-executed 159 * in the guest. 160 */ 161 kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); 162 return 0; 163} 164 165int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, 166 phys_addr_t fault_ipa) 167{ 168 struct kvm_exit_mmio mmio; 169 unsigned long data; 170 unsigned long rt; 171 int ret; 172 173 /* 174 * Prepare MMIO operation. First stash it in a private 175 * structure that we can use for in-kernel emulation. If the 176 * kernel can't handle it, copy it into run->mmio and let user 177 * space do its magic. 178 */ 179 180 if (kvm_vcpu_dabt_isvalid(vcpu)) { 181 ret = decode_hsr(vcpu, fault_ipa, &mmio); 182 if (ret) 183 return ret; 184 } else { 185 kvm_err("load/store instruction decoding not implemented\n"); 186 return -ENOSYS; 187 } 188 189 rt = vcpu->arch.mmio_decode.rt; 190 data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), mmio.len); 191 192 trace_kvm_mmio((mmio.is_write) ? KVM_TRACE_MMIO_WRITE : 193 KVM_TRACE_MMIO_READ_UNSATISFIED, 194 mmio.len, fault_ipa, 195 (mmio.is_write) ? data : 0); 196 197 if (mmio.is_write) 198 mmio_write_buf(mmio.data, mmio.len, data); 199 200 if (vgic_handle_mmio(vcpu, run, &mmio)) 201 return 1; 202 203 kvm_prepare_mmio(run, &mmio); 204 return 0; 205} 206