KVM
Functions | Variables
aarch32.c File Reference
#include <linux/kvm_host.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_hyp.h>
Include dependency graph for aarch32.c:

Go to the source code of this file.

Functions

bool kvm_condition_valid32 (const struct kvm_vcpu *vcpu)
 
static void kvm_adjust_itstate (struct kvm_vcpu *vcpu)
 
void kvm_skip_instr32 (struct kvm_vcpu *vcpu)
 

Variables

static const unsigned short cc_map [16]
 

Function Documentation

◆ kvm_adjust_itstate()

static void kvm_adjust_itstate ( struct kvm_vcpu *  vcpu)
static

adjust_itstate - adjust ITSTATE when emulating instructions in IT-block @vcpu: The VCPU pointer

When exceptions occur while instructions are executed in Thumb IF-THEN blocks, the ITSTATE field of the CPSR is not advanced (updated), so we have to do this little bit of work manually. The fields map like this:

IT[7:0] -> CPSR[26:25],CPSR[15:10]

Definition at line 96 of file aarch32.c.

97 {
98  unsigned long itbits, cond;
99  unsigned long cpsr = *vcpu_cpsr(vcpu);
100  bool is_arm = !(cpsr & PSR_AA32_T_BIT);
101 
102  if (is_arm || !(cpsr & PSR_AA32_IT_MASK))
103  return;
104 
105  cond = (cpsr & 0xe000) >> 13;
106  itbits = (cpsr & 0x1c00) >> (10 - 2);
107  itbits |= (cpsr & (0x3 << 25)) >> 25;
108 
109  /* Perform ITAdvance (see page A2-52 in ARM DDI 0406C) */
110  if ((itbits & 0x7) == 0)
111  itbits = cond = 0;
112  else
113  itbits = (itbits << 1) & 0x1f;
114 
115  cpsr &= ~PSR_AA32_IT_MASK;
116  cpsr |= cond << 13;
117  cpsr |= (itbits & 0x1c) << (10 - 2);
118  cpsr |= (itbits & 0x3) << 25;
119  *vcpu_cpsr(vcpu) = cpsr;
120 }
Here is the caller graph for this function:

◆ kvm_condition_valid32()

bool kvm_condition_valid32 ( const struct kvm_vcpu *  vcpu)

Definition at line 47 of file aarch32.c.

48 {
49  unsigned long cpsr;
50  u32 cpsr_cond;
51  int cond;
52 
53  /* Top two bits non-zero? Unconditional. */
54  if (kvm_vcpu_get_esr(vcpu) >> 30)
55  return true;
56 
57  /* Is condition field valid? */
58  cond = kvm_vcpu_get_condition(vcpu);
59  if (cond == 0xE)
60  return true;
61 
62  cpsr = *vcpu_cpsr(vcpu);
63 
64  if (cond < 0) {
65  /* This can happen in Thumb mode: examine IT state. */
66  unsigned long it;
67 
68  it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3);
69 
70  /* it == 0 => unconditional. */
71  if (it == 0)
72  return true;
73 
74  /* The cond for this insn works out as the top 4 bits. */
75  cond = (it >> 4);
76  }
77 
78  cpsr_cond = cpsr >> 28;
79 
80  if (!((cc_map[cond] >> cpsr_cond) & 1))
81  return false;
82 
83  return true;
84 }
static const unsigned short cc_map[16]
Definition: aarch32.c:25

◆ kvm_skip_instr32()

void kvm_skip_instr32 ( struct kvm_vcpu *  vcpu)

kvm_skip_instr - skip a trapped instruction and proceed to the next @vcpu: The vcpu pointer

Definition at line 126 of file aarch32.c.

127 {
128  u32 pc = *vcpu_pc(vcpu);
129  bool is_thumb;
130 
131  is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_AA32_T_BIT);
132  if (is_thumb && !kvm_vcpu_trap_il_is32bit(vcpu))
133  pc += 2;
134  else
135  pc += 4;
136 
137  *vcpu_pc(vcpu) = pc;
138 
139  kvm_adjust_itstate(vcpu);
140 }
static void kvm_adjust_itstate(struct kvm_vcpu *vcpu)
Definition: aarch32.c:96
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ cc_map

const unsigned short cc_map[16]
static
Initial value:
= {
0xF0F0,
0x0F0F,
0xCCCC,
0x3333,
0xFF00,
0x00FF,
0xAAAA,
0x5555,
0x0C0C,
0xF3F3,
0xAA55,
0x55AA,
0x0A05,
0xF5FA,
0xFFFF,
0
}

Definition at line 25 of file aarch32.c.