3 #include "config-host.h"
14 extern kvm_context_t kvm_context
;
16 static uint64_t map_addr(struct kvm_sregs
*sregs
, target_ulong virt
, unsigned *perms
)
18 uint64_t mask
= ((1ull << 48) - 1) & ~4095ull;
22 if (sregs
->cr4
& 0x20) {
24 p
= ldq_phys(p
+ 8 * (virt
>> 30));
28 p
= ldq_phys(p
+ 8 * ((virt
>> 21) & 511));
33 p
+= ((virt
>> 12) & 511) << 12;
36 p
= ldq_phys(p
+ 8 * ((virt
>> 12) & 511));
43 p
= ldl_phys(p
+ 4 * ((virt
>> 22) & 1023));
48 p
+= ((virt
>> 12) & 1023) << 12;
51 p
= ldl_phys(p
+ 4 * ((virt
>> 12) & 1023));
60 return p
+ (virt
& 4095);
63 static uint8_t read_byte_virt(CPUState
*env
, target_ulong virt
)
65 struct kvm_sregs sregs
;
67 kvm_get_sregs(kvm_context
, env
->cpu_index
, &sregs
);
68 return ldub_phys(map_addr(&sregs
, virt
, NULL
));
71 static void write_byte_virt(CPUState
*env
, target_ulong virt
, uint8_t b
)
73 struct kvm_sregs sregs
;
75 kvm_get_sregs(kvm_context
, env
->cpu_index
, &sregs
);
76 stb_phys(map_addr(&sregs
, virt
, NULL
), b
);
79 static uint32_t get_bios_map(CPUState
*env
, unsigned *perms
)
82 struct kvm_sregs sregs
;
84 kvm_get_sregs(kvm_context
, env
->cpu_index
, &sregs
);
86 for (v
= -4096u; v
!= 0; v
-= 4096)
87 if (map_addr(&sregs
, v
, perms
) == 0xe0000)
102 uint32_t set_tpr_eax
;
106 static struct vapic_bios vapic_bios
;
108 static uint32_t real_tpr
;
109 static uint32_t bios_addr
;
110 static uint32_t vapic_phys
;
111 static int bios_enabled
;
112 static uint32_t vbios_desc_phys
;
114 void update_vbios_real_tpr()
116 cpu_physical_memory_rw(vbios_desc_phys
, (void *)&vapic_bios
, sizeof vapic_bios
, 0);
117 vapic_bios
.real_tpr
= real_tpr
;
118 vapic_bios
.vcpu_shift
= 7;
119 cpu_physical_memory_rw(vbios_desc_phys
, (void *)&vapic_bios
, sizeof vapic_bios
, 1);
122 static unsigned modrm_reg(uint8_t modrm
)
124 return (modrm
>> 3) & 7;
127 static int is_abs_modrm(uint8_t modrm
)
129 return (modrm
& 0xc7) == 0x05;
132 static int instruction_is_ok(CPUState
*env
, uint64_t rip
, int is_write
)
135 unsigned addr_offset
;
139 if ((rip
& 0xf0000000) != 0x80000000 && (rip
& 0xf0000000) != 0xe0000000)
141 b1
= read_byte_virt(env
, rip
);
142 b2
= read_byte_virt(env
, rip
+ 1);
144 case 0xc7: /* mov imm32, r/m32 (c7/0) */
145 if (modrm_reg(b2
) != 0)
148 case 0x89: /* mov r32 to r/m32 */
149 case 0x8b: /* mov r/m32 to r32 */
150 if (!is_abs_modrm(b2
))
154 case 0xa1: /* mov abs to eax */
155 case 0xa3: /* mov eax to abs */
161 p
= rip
+ addr_offset
;
162 addr
= read_byte_virt(env
, p
++);
163 addr
|= read_byte_virt(env
, p
++) << 8;
164 addr
|= read_byte_virt(env
, p
++) << 16;
165 addr
|= read_byte_virt(env
, p
++) << 24;
166 if ((addr
& 0xfff) != 0x80)
169 update_vbios_real_tpr();
173 static int bios_is_mapped(CPUState
*env
, uint64_t rip
)
177 struct kvm_sregs sregs
;
180 uint32_t offset
, fixup
;
185 kvm_get_sregs(kvm_context
, env
->cpu_index
, &sregs
);
187 probe
= (rip
& 0xf0000000) + 0xe0000;
188 phys
= map_addr(&sregs
, probe
, &perms
);
192 for (i
= 0; i
< 64; ++i
) {
193 cpu_physical_memory_read(phys
, (void *)&vapic_bios
, sizeof(vapic_bios
));
194 if (memcmp(vapic_bios
.signature
, "kvm aPiC", 8) == 0)
201 if (bios_addr
== vapic_bios
.virt_base
)
203 vbios_desc_phys
= phys
;
204 for (i
= vapic_bios
.fixup_start
; i
< vapic_bios
.fixup_end
; i
+= 4) {
205 offset
= ldl_phys(phys
+ i
- vapic_bios
.virt_base
);
206 fixup
= phys
+ offset
;
207 stl_phys(fixup
, ldl_phys(fixup
) + bios_addr
- vapic_bios
.virt_base
);
209 vapic_phys
= vapic_bios
.vapic
- vapic_bios
.virt_base
+ phys
;
213 static int enable_vapic(CPUState
*env
)
215 struct kvm_sregs sregs
;
217 kvm_get_sregs(kvm_context
, env
->cpu_index
, &sregs
);
218 sregs
.tr
.selector
= 0xdb + (env
->cpu_index
<< 8);
219 kvm_set_sregs(kvm_context
, env
->cpu_index
, &sregs
);
221 kvm_enable_vapic(kvm_context
, env
->cpu_index
,
222 vapic_phys
+ (env
->cpu_index
<< 7));
226 static void patch_call(CPUState
*env
, uint64_t rip
, uint32_t target
)
230 offset
= target
- vapic_bios
.virt_base
+ bios_addr
- rip
- 5;
231 write_byte_virt(env
, rip
, 0xe8); /* call near */
232 write_byte_virt(env
, rip
+ 1, offset
);
233 write_byte_virt(env
, rip
+ 2, offset
>> 8);
234 write_byte_virt(env
, rip
+ 3, offset
>> 16);
235 write_byte_virt(env
, rip
+ 4, offset
>> 24);
238 static void patch_instruction(CPUState
*env
, uint64_t rip
)
242 b1
= read_byte_virt(env
, rip
);
243 b2
= read_byte_virt(env
, rip
+ 1);
245 case 0x89: /* mov r32 to r/m32 */
246 write_byte_virt(env
, rip
, 0x50 + modrm_reg(b2
)); /* push reg */
247 patch_call(env
, rip
+ 1, vapic_bios
.set_tpr
);
249 case 0x8b: /* mov r/m32 to r32 */
250 write_byte_virt(env
, rip
, 0x90);
251 patch_call(env
, rip
+ 1, vapic_bios
.get_tpr
[modrm_reg(b2
)]);
253 case 0xa1: /* mov abs to eax */
254 patch_call(env
, rip
, vapic_bios
.get_tpr
[0]);
256 case 0xa3: /* mov eax to abs */
257 patch_call(env
, rip
, vapic_bios
.set_tpr_eax
);
259 case 0xc7: /* mov imm32, r/m32 (c7/0) */
260 write_byte_virt(env
, rip
, 0x68); /* push imm32 */
261 write_byte_virt(env
, rip
+ 1, read_byte_virt(env
, rip
+6));
262 write_byte_virt(env
, rip
+ 2, read_byte_virt(env
, rip
+7));
263 write_byte_virt(env
, rip
+ 3, read_byte_virt(env
, rip
+8));
264 write_byte_virt(env
, rip
+ 4, read_byte_virt(env
, rip
+9));
265 patch_call(env
, rip
+ 5, vapic_bios
.set_tpr
);
268 printf("funny insn %02x %02x\n", b1
, b2
);
272 void kvm_tpr_access_report(CPUState
*env
, uint64_t rip
, int is_write
)
274 if (!instruction_is_ok(env
, rip
, is_write
))
276 if (!bios_is_mapped(env
, rip
))
278 if (!enable_vapic(env
))
280 patch_instruction(env
, rip
);
283 void kvm_tpr_opt_setup(CPUState
*env
)
287 kvm_enable_tpr_access_reporting(kvm_context
, env
->cpu_index
);