0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/kvm_host.h>
0014 #include <asm/kvm_emulate.h>
0015 #include <asm/kvm_hyp.h>
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 static const unsigned short cc_map[16] = {
0026 0xF0F0,
0027 0x0F0F,
0028 0xCCCC,
0029 0x3333,
0030 0xFF00,
0031 0x00FF,
0032 0xAAAA,
0033 0x5555,
0034 0x0C0C,
0035 0xF3F3,
0036 0xAA55,
0037 0x55AA,
0038 0x0A05,
0039 0xF5FA,
0040 0xFFFF,
0041 0
0042 };
0043
0044
0045
0046
0047 bool kvm_condition_valid32(const struct kvm_vcpu *vcpu)
0048 {
0049 unsigned long cpsr;
0050 u32 cpsr_cond;
0051 int cond;
0052
0053
0054 if (kvm_vcpu_get_esr(vcpu) >> 30)
0055 return true;
0056
0057
0058 cond = kvm_vcpu_get_condition(vcpu);
0059 if (cond == 0xE)
0060 return true;
0061
0062 cpsr = *vcpu_cpsr(vcpu);
0063
0064 if (cond < 0) {
0065
0066 unsigned long it;
0067
0068 it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3);
0069
0070
0071 if (it == 0)
0072 return true;
0073
0074
0075 cond = (it >> 4);
0076 }
0077
0078 cpsr_cond = cpsr >> 28;
0079
0080 if (!((cc_map[cond] >> cpsr_cond) & 1))
0081 return false;
0082
0083 return true;
0084 }
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 static void kvm_adjust_itstate(struct kvm_vcpu *vcpu)
0097 {
0098 unsigned long itbits, cond;
0099 unsigned long cpsr = *vcpu_cpsr(vcpu);
0100 bool is_arm = !(cpsr & PSR_AA32_T_BIT);
0101
0102 if (is_arm || !(cpsr & PSR_AA32_IT_MASK))
0103 return;
0104
0105 cond = (cpsr & 0xe000) >> 13;
0106 itbits = (cpsr & 0x1c00) >> (10 - 2);
0107 itbits |= (cpsr & (0x3 << 25)) >> 25;
0108
0109
0110 if ((itbits & 0x7) == 0)
0111 itbits = cond = 0;
0112 else
0113 itbits = (itbits << 1) & 0x1f;
0114
0115 cpsr &= ~PSR_AA32_IT_MASK;
0116 cpsr |= cond << 13;
0117 cpsr |= (itbits & 0x1c) << (10 - 2);
0118 cpsr |= (itbits & 0x3) << 25;
0119 *vcpu_cpsr(vcpu) = cpsr;
0120 }
0121
0122
0123
0124
0125
0126 void kvm_skip_instr32(struct kvm_vcpu *vcpu)
0127 {
0128 u32 pc = *vcpu_pc(vcpu);
0129 bool is_thumb;
0130
0131 is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_AA32_T_BIT);
0132 if (is_thumb && !kvm_vcpu_trap_il_is32bit(vcpu))
0133 pc += 2;
0134 else
0135 pc += 4;
0136
0137 *vcpu_pc(vcpu) = pc;
0138
0139 kvm_adjust_itstate(vcpu);
0140 }