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_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data); 119 } 120 121 return 0; 122} 123 124static int decode_hsr(struct kvm_vcpu *vcpu, bool *is_write, int *len) 125{ 126 unsigned long rt; 127 int access_size; 128 bool sign_extend; 129 130 if (kvm_vcpu_dabt_isextabt(vcpu)) { 131 /* cache operation on I/O addr, tell guest unsupported */ 132 kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu)); 133 return 1; 134 } 135 136 if (kvm_vcpu_dabt_iss1tw(vcpu)) { 137 /* page table accesses IO mem: tell guest to fix its TTBR */ 138 kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu)); 139 return 1; 140 } 141 142 access_size = kvm_vcpu_dabt_get_as(vcpu); 143 if (unlikely(access_size < 0)) 144 return access_size; 145 146 *is_write = kvm_vcpu_dabt_iswrite(vcpu); 147 sign_extend = kvm_vcpu_dabt_issext(vcpu); 148 rt = kvm_vcpu_dabt_get_rd(vcpu); 149 150 *len = access_size; 151 vcpu->arch.mmio_decode.sign_extend = sign_extend; 152 vcpu->arch.mmio_decode.rt = rt; 153 154 /* 155 * The MMIO instruction is emulated and should not be re-executed 156 * in the guest. 157 */ 158 kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); 159 return 0; 160} 161 162int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, 163 phys_addr_t fault_ipa) 164{ 165 unsigned long data; 166 unsigned long rt; 167 int ret; 168 bool is_write; 169 int len; 170 u8 data_buf[8]; 171 172 /* 173 * Prepare MMIO operation. First decode the syndrome data we get 174 * from the CPU. Then try if some in-kernel emulation feels 175 * responsible, otherwise let user space do its magic. 176 */ 177 if (kvm_vcpu_dabt_isvalid(vcpu)) { 178 ret = decode_hsr(vcpu, &is_write, &len); 179 if (ret) 180 return ret; 181 } else { 182 kvm_err("load/store instruction decoding not implemented\n"); 183 return -ENOSYS; 184 } 185 186 rt = vcpu->arch.mmio_decode.rt; 187 188 if (is_write) { 189 data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt), 190 len); 191 192 trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data); 193 mmio_write_buf(data_buf, len, data); 194 195 ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len, 196 data_buf); 197 } else { 198 trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len, 199 fault_ipa, 0); 200 201 ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len, 202 data_buf); 203 } 204 205 /* Now prepare kvm_run for the potential return to userland. */ 206 run->mmio.is_write = is_write; 207 run->mmio.phys_addr = fault_ipa; 208 run->mmio.len = len; 209 memcpy(run->mmio.data, data_buf, len); 210 211 if (!ret) { 212 /* We handled the access successfully in the kernel. */ 213 kvm_handle_mmio_return(vcpu, run); 214 return 1; 215 } 216 217 run->exit_reason = KVM_EXIT_MMIO; 218 return 0; 219} 220