Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.9-rc8 279 lines 6.7 kB view raw
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#ifndef __ARM_KVM_EMULATE_H__ 20#define __ARM_KVM_EMULATE_H__ 21 22#include <linux/kvm_host.h> 23#include <asm/kvm_asm.h> 24#include <asm/kvm_mmio.h> 25#include <asm/kvm_arm.h> 26#include <asm/cputype.h> 27 28unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num); 29unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu); 30 31static inline unsigned long vcpu_get_reg(struct kvm_vcpu *vcpu, 32 u8 reg_num) 33{ 34 return *vcpu_reg(vcpu, reg_num); 35} 36 37static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num, 38 unsigned long val) 39{ 40 *vcpu_reg(vcpu, reg_num) = val; 41} 42 43bool kvm_condition_valid32(const struct kvm_vcpu *vcpu); 44void kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr); 45void kvm_inject_undefined(struct kvm_vcpu *vcpu); 46void kvm_inject_vabt(struct kvm_vcpu *vcpu); 47void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); 48void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); 49 50static inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu) 51{ 52 return kvm_condition_valid32(vcpu); 53} 54 55static inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr) 56{ 57 kvm_skip_instr32(vcpu, is_wide_instr); 58} 59 60static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) 61{ 62 vcpu->arch.hcr = HCR_GUEST_MASK; 63} 64 65static inline unsigned long vcpu_get_hcr(const struct kvm_vcpu *vcpu) 66{ 67 return vcpu->arch.hcr; 68} 69 70static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr) 71{ 72 vcpu->arch.hcr = hcr; 73} 74 75static inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu) 76{ 77 return 1; 78} 79 80static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu) 81{ 82 return &vcpu->arch.ctxt.gp_regs.usr_regs.ARM_pc; 83} 84 85static inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu) 86{ 87 return (unsigned long *)&vcpu->arch.ctxt.gp_regs.usr_regs.ARM_cpsr; 88} 89 90static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu) 91{ 92 *vcpu_cpsr(vcpu) |= PSR_T_BIT; 93} 94 95static inline bool mode_has_spsr(struct kvm_vcpu *vcpu) 96{ 97 unsigned long cpsr_mode = vcpu->arch.ctxt.gp_regs.usr_regs.ARM_cpsr & MODE_MASK; 98 return (cpsr_mode > USR_MODE && cpsr_mode < SYSTEM_MODE); 99} 100 101static inline bool vcpu_mode_priv(struct kvm_vcpu *vcpu) 102{ 103 unsigned long cpsr_mode = vcpu->arch.ctxt.gp_regs.usr_regs.ARM_cpsr & MODE_MASK; 104 return cpsr_mode > USR_MODE;; 105} 106 107static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu) 108{ 109 return vcpu->arch.fault.hsr; 110} 111 112static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu) 113{ 114 u32 hsr = kvm_vcpu_get_hsr(vcpu); 115 116 if (hsr & HSR_CV) 117 return (hsr & HSR_COND) >> HSR_COND_SHIFT; 118 119 return -1; 120} 121 122static inline unsigned long kvm_vcpu_get_hfar(struct kvm_vcpu *vcpu) 123{ 124 return vcpu->arch.fault.hxfar; 125} 126 127static inline phys_addr_t kvm_vcpu_get_fault_ipa(struct kvm_vcpu *vcpu) 128{ 129 return ((phys_addr_t)vcpu->arch.fault.hpfar & HPFAR_MASK) << 8; 130} 131 132static inline bool kvm_vcpu_dabt_isvalid(struct kvm_vcpu *vcpu) 133{ 134 return kvm_vcpu_get_hsr(vcpu) & HSR_ISV; 135} 136 137static inline bool kvm_vcpu_dabt_iswrite(struct kvm_vcpu *vcpu) 138{ 139 return kvm_vcpu_get_hsr(vcpu) & HSR_WNR; 140} 141 142static inline bool kvm_vcpu_dabt_issext(struct kvm_vcpu *vcpu) 143{ 144 return kvm_vcpu_get_hsr(vcpu) & HSR_SSE; 145} 146 147static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu) 148{ 149 return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT; 150} 151 152static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu) 153{ 154 return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_EA; 155} 156 157static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu) 158{ 159 return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW; 160} 161 162static inline bool kvm_vcpu_dabt_is_cm(struct kvm_vcpu *vcpu) 163{ 164 return !!(kvm_vcpu_get_hsr(vcpu) & HSR_DABT_CM); 165} 166 167/* Get Access Size from a data abort */ 168static inline int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu) 169{ 170 switch ((kvm_vcpu_get_hsr(vcpu) >> 22) & 0x3) { 171 case 0: 172 return 1; 173 case 1: 174 return 2; 175 case 2: 176 return 4; 177 default: 178 kvm_err("Hardware is weird: SAS 0b11 is reserved\n"); 179 return -EFAULT; 180 } 181} 182 183/* This one is not specific to Data Abort */ 184static inline bool kvm_vcpu_trap_il_is32bit(struct kvm_vcpu *vcpu) 185{ 186 return kvm_vcpu_get_hsr(vcpu) & HSR_IL; 187} 188 189static inline u8 kvm_vcpu_trap_get_class(struct kvm_vcpu *vcpu) 190{ 191 return kvm_vcpu_get_hsr(vcpu) >> HSR_EC_SHIFT; 192} 193 194static inline bool kvm_vcpu_trap_is_iabt(struct kvm_vcpu *vcpu) 195{ 196 return kvm_vcpu_trap_get_class(vcpu) == HSR_EC_IABT; 197} 198 199static inline u8 kvm_vcpu_trap_get_fault(struct kvm_vcpu *vcpu) 200{ 201 return kvm_vcpu_get_hsr(vcpu) & HSR_FSC; 202} 203 204static inline u8 kvm_vcpu_trap_get_fault_type(struct kvm_vcpu *vcpu) 205{ 206 return kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE; 207} 208 209static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu) 210{ 211 return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK; 212} 213 214static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu) 215{ 216 return vcpu_cp15(vcpu, c0_MPIDR) & MPIDR_HWID_BITMASK; 217} 218 219static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu) 220{ 221 *vcpu_cpsr(vcpu) |= PSR_E_BIT; 222} 223 224static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu) 225{ 226 return !!(*vcpu_cpsr(vcpu) & PSR_E_BIT); 227} 228 229static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu, 230 unsigned long data, 231 unsigned int len) 232{ 233 if (kvm_vcpu_is_be(vcpu)) { 234 switch (len) { 235 case 1: 236 return data & 0xff; 237 case 2: 238 return be16_to_cpu(data & 0xffff); 239 default: 240 return be32_to_cpu(data); 241 } 242 } else { 243 switch (len) { 244 case 1: 245 return data & 0xff; 246 case 2: 247 return le16_to_cpu(data & 0xffff); 248 default: 249 return le32_to_cpu(data); 250 } 251 } 252} 253 254static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, 255 unsigned long data, 256 unsigned int len) 257{ 258 if (kvm_vcpu_is_be(vcpu)) { 259 switch (len) { 260 case 1: 261 return data & 0xff; 262 case 2: 263 return cpu_to_be16(data & 0xffff); 264 default: 265 return cpu_to_be32(data); 266 } 267 } else { 268 switch (len) { 269 case 1: 270 return data & 0xff; 271 case 2: 272 return cpu_to_le16(data & 0xffff); 273 default: 274 return cpu_to_le32(data); 275 } 276 } 277} 278 279#endif /* __ARM_KVM_EMULATE_H__ */