root / target-arm / kvm.c @ eb035b48
History | View | Annotate | Download (14.2 kB)
1 |
/*
|
---|---|
2 |
* ARM implementation of KVM hooks
|
3 |
*
|
4 |
* Copyright Christoffer Dall 2009-2010
|
5 |
*
|
6 |
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
7 |
* See the COPYING file in the top-level directory.
|
8 |
*
|
9 |
*/
|
10 |
|
11 |
#include <stdio.h> |
12 |
#include <sys/types.h> |
13 |
#include <sys/ioctl.h> |
14 |
#include <sys/mman.h> |
15 |
|
16 |
#include <linux/kvm.h> |
17 |
|
18 |
#include "qemu-common.h" |
19 |
#include "qemu/timer.h" |
20 |
#include "sysemu/sysemu.h" |
21 |
#include "sysemu/kvm.h" |
22 |
#include "kvm_arm.h" |
23 |
#include "cpu.h" |
24 |
#include "hw/arm-misc.h" |
25 |
|
26 |
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
27 |
KVM_CAP_LAST_INFO |
28 |
}; |
29 |
|
30 |
int kvm_arch_init(KVMState *s)
|
31 |
{ |
32 |
/* For ARM interrupt delivery is always asynchronous,
|
33 |
* whether we are using an in-kernel VGIC or not.
|
34 |
*/
|
35 |
kvm_async_interrupts_allowed = true;
|
36 |
return 0; |
37 |
} |
38 |
|
39 |
unsigned long kvm_arch_vcpu_id(CPUState *cpu) |
40 |
{ |
41 |
return cpu->cpu_index;
|
42 |
} |
43 |
|
44 |
int kvm_arch_init_vcpu(CPUState *cs)
|
45 |
{ |
46 |
struct kvm_vcpu_init init;
|
47 |
int ret;
|
48 |
uint64_t v; |
49 |
struct kvm_one_reg r;
|
50 |
|
51 |
init.target = KVM_ARM_TARGET_CORTEX_A15; |
52 |
memset(init.features, 0, sizeof(init.features)); |
53 |
ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); |
54 |
if (ret) {
|
55 |
return ret;
|
56 |
} |
57 |
/* Query the kernel to make sure it supports 32 VFP
|
58 |
* registers: QEMU's "cortex-a15" CPU is always a
|
59 |
* VFP-D32 core. The simplest way to do this is just
|
60 |
* to attempt to read register d31.
|
61 |
*/
|
62 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;
|
63 |
r.addr = (uintptr_t)(&v); |
64 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
65 |
if (ret == ENOENT) {
|
66 |
return EINVAL;
|
67 |
} |
68 |
return ret;
|
69 |
} |
70 |
|
71 |
/* We track all the KVM devices which need their memory addresses
|
72 |
* passing to the kernel in a list of these structures.
|
73 |
* When board init is complete we run through the list and
|
74 |
* tell the kernel the base addresses of the memory regions.
|
75 |
* We use a MemoryListener to track mapping and unmapping of
|
76 |
* the regions during board creation, so the board models don't
|
77 |
* need to do anything special for the KVM case.
|
78 |
*/
|
79 |
typedef struct KVMDevice { |
80 |
struct kvm_arm_device_addr kda;
|
81 |
MemoryRegion *mr; |
82 |
QSLIST_ENTRY(KVMDevice) entries; |
83 |
} KVMDevice; |
84 |
|
85 |
static QSLIST_HEAD(kvm_devices_head, KVMDevice) kvm_devices_head;
|
86 |
|
87 |
static void kvm_arm_devlistener_add(MemoryListener *listener, |
88 |
MemoryRegionSection *section) |
89 |
{ |
90 |
KVMDevice *kd; |
91 |
|
92 |
QSLIST_FOREACH(kd, &kvm_devices_head, entries) { |
93 |
if (section->mr == kd->mr) {
|
94 |
kd->kda.addr = section->offset_within_address_space; |
95 |
} |
96 |
} |
97 |
} |
98 |
|
99 |
static void kvm_arm_devlistener_del(MemoryListener *listener, |
100 |
MemoryRegionSection *section) |
101 |
{ |
102 |
KVMDevice *kd; |
103 |
|
104 |
QSLIST_FOREACH(kd, &kvm_devices_head, entries) { |
105 |
if (section->mr == kd->mr) {
|
106 |
kd->kda.addr = -1;
|
107 |
} |
108 |
} |
109 |
} |
110 |
|
111 |
static MemoryListener devlistener = {
|
112 |
.region_add = kvm_arm_devlistener_add, |
113 |
.region_del = kvm_arm_devlistener_del, |
114 |
}; |
115 |
|
116 |
static void kvm_arm_machine_init_done(Notifier *notifier, void *data) |
117 |
{ |
118 |
KVMDevice *kd, *tkd; |
119 |
|
120 |
memory_listener_unregister(&devlistener); |
121 |
QSLIST_FOREACH_SAFE(kd, &kvm_devices_head, entries, tkd) { |
122 |
if (kd->kda.addr != -1) { |
123 |
if (kvm_vm_ioctl(kvm_state, KVM_ARM_SET_DEVICE_ADDR,
|
124 |
&kd->kda) < 0) {
|
125 |
fprintf(stderr, "KVM_ARM_SET_DEVICE_ADDRESS failed: %s\n",
|
126 |
strerror(errno)); |
127 |
abort(); |
128 |
} |
129 |
} |
130 |
g_free(kd); |
131 |
} |
132 |
} |
133 |
|
134 |
static Notifier notify = {
|
135 |
.notify = kvm_arm_machine_init_done, |
136 |
}; |
137 |
|
138 |
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid)
|
139 |
{ |
140 |
KVMDevice *kd; |
141 |
|
142 |
if (!kvm_irqchip_in_kernel()) {
|
143 |
return;
|
144 |
} |
145 |
|
146 |
if (QSLIST_EMPTY(&kvm_devices_head)) {
|
147 |
memory_listener_register(&devlistener, NULL);
|
148 |
qemu_add_machine_init_done_notifier(¬ify); |
149 |
} |
150 |
kd = g_new0(KVMDevice, 1);
|
151 |
kd->mr = mr; |
152 |
kd->kda.id = devid; |
153 |
kd->kda.addr = -1;
|
154 |
QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries); |
155 |
} |
156 |
|
157 |
typedef struct Reg { |
158 |
uint64_t id; |
159 |
int offset;
|
160 |
} Reg; |
161 |
|
162 |
#define COREREG(KERNELNAME, QEMUFIELD) \
|
163 |
{ \ |
164 |
KVM_REG_ARM | KVM_REG_SIZE_U32 | \ |
165 |
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(KERNELNAME), \ |
166 |
offsetof(CPUARMState, QEMUFIELD) \ |
167 |
} |
168 |
|
169 |
#define CP15REG(CRN, CRM, OPC1, OPC2, QEMUFIELD) \
|
170 |
{ \ |
171 |
KVM_REG_ARM | KVM_REG_SIZE_U32 | \ |
172 |
(15 << KVM_REG_ARM_COPROC_SHIFT) | \
|
173 |
((CRN) << KVM_REG_ARM_32_CRN_SHIFT) | \ |
174 |
((CRM) << KVM_REG_ARM_CRM_SHIFT) | \ |
175 |
((OPC1) << KVM_REG_ARM_OPC1_SHIFT) | \ |
176 |
((OPC2) << KVM_REG_ARM_32_OPC2_SHIFT), \ |
177 |
offsetof(CPUARMState, QEMUFIELD) \ |
178 |
} |
179 |
|
180 |
#define VFPSYSREG(R) \
|
181 |
{ \ |
182 |
KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | \ |
183 |
KVM_REG_ARM_VFP_##R, \ |
184 |
offsetof(CPUARMState, vfp.xregs[ARM_VFP_##R]) \ |
185 |
} |
186 |
|
187 |
static const Reg regs[] = { |
188 |
/* R0_usr .. R14_usr */
|
189 |
COREREG(usr_regs.uregs[0], regs[0]), |
190 |
COREREG(usr_regs.uregs[1], regs[1]), |
191 |
COREREG(usr_regs.uregs[2], regs[2]), |
192 |
COREREG(usr_regs.uregs[3], regs[3]), |
193 |
COREREG(usr_regs.uregs[4], regs[4]), |
194 |
COREREG(usr_regs.uregs[5], regs[5]), |
195 |
COREREG(usr_regs.uregs[6], regs[6]), |
196 |
COREREG(usr_regs.uregs[7], regs[7]), |
197 |
COREREG(usr_regs.uregs[8], usr_regs[0]), |
198 |
COREREG(usr_regs.uregs[9], usr_regs[1]), |
199 |
COREREG(usr_regs.uregs[10], usr_regs[2]), |
200 |
COREREG(usr_regs.uregs[11], usr_regs[3]), |
201 |
COREREG(usr_regs.uregs[12], usr_regs[4]), |
202 |
COREREG(usr_regs.uregs[13], banked_r13[0]), |
203 |
COREREG(usr_regs.uregs[14], banked_r14[0]), |
204 |
/* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
|
205 |
COREREG(svc_regs[0], banked_r13[1]), |
206 |
COREREG(svc_regs[1], banked_r14[1]), |
207 |
COREREG(svc_regs[2], banked_spsr[1]), |
208 |
COREREG(abt_regs[0], banked_r13[2]), |
209 |
COREREG(abt_regs[1], banked_r14[2]), |
210 |
COREREG(abt_regs[2], banked_spsr[2]), |
211 |
COREREG(und_regs[0], banked_r13[3]), |
212 |
COREREG(und_regs[1], banked_r14[3]), |
213 |
COREREG(und_regs[2], banked_spsr[3]), |
214 |
COREREG(irq_regs[0], banked_r13[4]), |
215 |
COREREG(irq_regs[1], banked_r14[4]), |
216 |
COREREG(irq_regs[2], banked_spsr[4]), |
217 |
/* R8_fiq .. R14_fiq and SPSR_fiq */
|
218 |
COREREG(fiq_regs[0], fiq_regs[0]), |
219 |
COREREG(fiq_regs[1], fiq_regs[1]), |
220 |
COREREG(fiq_regs[2], fiq_regs[2]), |
221 |
COREREG(fiq_regs[3], fiq_regs[3]), |
222 |
COREREG(fiq_regs[4], fiq_regs[4]), |
223 |
COREREG(fiq_regs[5], banked_r13[5]), |
224 |
COREREG(fiq_regs[6], banked_r14[5]), |
225 |
COREREG(fiq_regs[7], banked_spsr[5]), |
226 |
/* R15 */
|
227 |
COREREG(usr_regs.uregs[15], regs[15]), |
228 |
/* A non-comprehensive set of cp15 registers.
|
229 |
* TODO: drive this from the cp_regs hashtable instead.
|
230 |
*/
|
231 |
CP15REG(1, 0, 0, 0, cp15.c1_sys), /* SCTLR */ |
232 |
CP15REG(2, 0, 0, 2, cp15.c2_control), /* TTBCR */ |
233 |
CP15REG(3, 0, 0, 0, cp15.c3), /* DACR */ |
234 |
/* VFP system registers */
|
235 |
VFPSYSREG(FPSID), |
236 |
VFPSYSREG(MVFR1), |
237 |
VFPSYSREG(MVFR0), |
238 |
VFPSYSREG(FPEXC), |
239 |
VFPSYSREG(FPINST), |
240 |
VFPSYSREG(FPINST2), |
241 |
}; |
242 |
|
243 |
int kvm_arch_put_registers(CPUState *cs, int level) |
244 |
{ |
245 |
ARMCPU *cpu = ARM_CPU(cs); |
246 |
CPUARMState *env = &cpu->env; |
247 |
struct kvm_one_reg r;
|
248 |
int mode, bn;
|
249 |
int ret, i;
|
250 |
uint32_t cpsr, fpscr; |
251 |
uint64_t ttbr; |
252 |
|
253 |
/* Make sure the banked regs are properly set */
|
254 |
mode = env->uncached_cpsr & CPSR_M; |
255 |
bn = bank_number(mode); |
256 |
if (mode == ARM_CPU_MODE_FIQ) {
|
257 |
memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t)); |
258 |
} else {
|
259 |
memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t)); |
260 |
} |
261 |
env->banked_r13[bn] = env->regs[13];
|
262 |
env->banked_r14[bn] = env->regs[14];
|
263 |
env->banked_spsr[bn] = env->spsr; |
264 |
|
265 |
/* Now we can safely copy stuff down to the kernel */
|
266 |
for (i = 0; i < ARRAY_SIZE(regs); i++) { |
267 |
r.id = regs[i].id; |
268 |
r.addr = (uintptr_t)(env) + regs[i].offset; |
269 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
270 |
if (ret) {
|
271 |
return ret;
|
272 |
} |
273 |
} |
274 |
|
275 |
/* Special cases which aren't a single CPUARMState field */
|
276 |
cpsr = cpsr_read(env); |
277 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | |
278 |
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr); |
279 |
r.addr = (uintptr_t)(&cpsr); |
280 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
281 |
if (ret) {
|
282 |
return ret;
|
283 |
} |
284 |
|
285 |
/* TTBR0: cp15 crm=2 opc1=0 */
|
286 |
ttbr = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
|
287 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
|
288 |
(2 << KVM_REG_ARM_CRM_SHIFT) | (0 << KVM_REG_ARM_OPC1_SHIFT); |
289 |
r.addr = (uintptr_t)(&ttbr); |
290 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
291 |
if (ret) {
|
292 |
return ret;
|
293 |
} |
294 |
|
295 |
/* TTBR1: cp15 crm=2 opc1=1 */
|
296 |
ttbr = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
|
297 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
|
298 |
(2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT); |
299 |
r.addr = (uintptr_t)(&ttbr); |
300 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
301 |
if (ret) {
|
302 |
return ret;
|
303 |
} |
304 |
|
305 |
/* VFP registers */
|
306 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP; |
307 |
for (i = 0; i < 32; i++) { |
308 |
r.addr = (uintptr_t)(&env->vfp.regs[i]); |
309 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
310 |
if (ret) {
|
311 |
return ret;
|
312 |
} |
313 |
r.id++; |
314 |
} |
315 |
|
316 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | |
317 |
KVM_REG_ARM_VFP_FPSCR; |
318 |
fpscr = vfp_get_fpscr(env); |
319 |
r.addr = (uintptr_t)&fpscr; |
320 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
321 |
|
322 |
return ret;
|
323 |
} |
324 |
|
325 |
int kvm_arch_get_registers(CPUState *cs)
|
326 |
{ |
327 |
ARMCPU *cpu = ARM_CPU(cs); |
328 |
CPUARMState *env = &cpu->env; |
329 |
struct kvm_one_reg r;
|
330 |
int mode, bn;
|
331 |
int ret, i;
|
332 |
uint32_t cpsr, fpscr; |
333 |
uint64_t ttbr; |
334 |
|
335 |
for (i = 0; i < ARRAY_SIZE(regs); i++) { |
336 |
r.id = regs[i].id; |
337 |
r.addr = (uintptr_t)(env) + regs[i].offset; |
338 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
339 |
if (ret) {
|
340 |
return ret;
|
341 |
} |
342 |
} |
343 |
|
344 |
/* Special cases which aren't a single CPUARMState field */
|
345 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | |
346 |
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr); |
347 |
r.addr = (uintptr_t)(&cpsr); |
348 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
349 |
if (ret) {
|
350 |
return ret;
|
351 |
} |
352 |
cpsr_write(env, cpsr, 0xffffffff);
|
353 |
|
354 |
/* TTBR0: cp15 crm=2 opc1=0 */
|
355 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
|
356 |
(2 << KVM_REG_ARM_CRM_SHIFT) | (0 << KVM_REG_ARM_OPC1_SHIFT); |
357 |
r.addr = (uintptr_t)(&ttbr); |
358 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
359 |
if (ret) {
|
360 |
return ret;
|
361 |
} |
362 |
env->cp15.c2_base0_hi = ttbr >> 32;
|
363 |
env->cp15.c2_base0 = ttbr; |
364 |
|
365 |
/* TTBR1: cp15 crm=2 opc1=1 */
|
366 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
|
367 |
(2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT); |
368 |
r.addr = (uintptr_t)(&ttbr); |
369 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
370 |
if (ret) {
|
371 |
return ret;
|
372 |
} |
373 |
env->cp15.c2_base1_hi = ttbr >> 32;
|
374 |
env->cp15.c2_base1 = ttbr; |
375 |
|
376 |
/* Make sure the current mode regs are properly set */
|
377 |
mode = env->uncached_cpsr & CPSR_M; |
378 |
bn = bank_number(mode); |
379 |
if (mode == ARM_CPU_MODE_FIQ) {
|
380 |
memcpy(env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t)); |
381 |
} else {
|
382 |
memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t)); |
383 |
} |
384 |
env->regs[13] = env->banked_r13[bn];
|
385 |
env->regs[14] = env->banked_r14[bn];
|
386 |
env->spsr = env->banked_spsr[bn]; |
387 |
|
388 |
/* The main GET_ONE_REG loop above set c2_control, but we need to
|
389 |
* update some extra cached precomputed values too.
|
390 |
* When this is driven from the cp_regs hashtable then this ugliness
|
391 |
* can disappear because we'll use the access function which sets
|
392 |
* these values automatically.
|
393 |
*/
|
394 |
env->cp15.c2_mask = ~(0xffffffffu >> env->cp15.c2_control);
|
395 |
env->cp15.c2_base_mask = ~(0x3fffu >> env->cp15.c2_control);
|
396 |
|
397 |
/* VFP registers */
|
398 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP; |
399 |
for (i = 0; i < 32; i++) { |
400 |
r.addr = (uintptr_t)(&env->vfp.regs[i]); |
401 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
402 |
if (ret) {
|
403 |
return ret;
|
404 |
} |
405 |
r.id++; |
406 |
} |
407 |
|
408 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | |
409 |
KVM_REG_ARM_VFP_FPSCR; |
410 |
r.addr = (uintptr_t)&fpscr; |
411 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
412 |
if (ret) {
|
413 |
return ret;
|
414 |
} |
415 |
vfp_set_fpscr(env, fpscr); |
416 |
|
417 |
return 0; |
418 |
} |
419 |
|
420 |
void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) |
421 |
{ |
422 |
} |
423 |
|
424 |
void kvm_arch_post_run(CPUState *cs, struct kvm_run *run) |
425 |
{ |
426 |
} |
427 |
|
428 |
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) |
429 |
{ |
430 |
return 0; |
431 |
} |
432 |
|
433 |
void kvm_arch_reset_vcpu(CPUState *cs)
|
434 |
{ |
435 |
} |
436 |
|
437 |
bool kvm_arch_stop_on_emulation_error(CPUState *cs)
|
438 |
{ |
439 |
return true; |
440 |
} |
441 |
|
442 |
int kvm_arch_process_async_events(CPUState *cs)
|
443 |
{ |
444 |
return 0; |
445 |
} |
446 |
|
447 |
int kvm_arch_on_sigbus_vcpu(CPUState *cs, int code, void *addr) |
448 |
{ |
449 |
return 1; |
450 |
} |
451 |
|
452 |
int kvm_arch_on_sigbus(int code, void *addr) |
453 |
{ |
454 |
return 1; |
455 |
} |
456 |
|
457 |
void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg) |
458 |
{ |
459 |
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
|
460 |
} |
461 |
|
462 |
int kvm_arch_insert_sw_breakpoint(CPUState *cs,
|
463 |
struct kvm_sw_breakpoint *bp)
|
464 |
{ |
465 |
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
|
466 |
return -EINVAL;
|
467 |
} |
468 |
|
469 |
int kvm_arch_insert_hw_breakpoint(target_ulong addr,
|
470 |
target_ulong len, int type)
|
471 |
{ |
472 |
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
|
473 |
return -EINVAL;
|
474 |
} |
475 |
|
476 |
int kvm_arch_remove_hw_breakpoint(target_ulong addr,
|
477 |
target_ulong len, int type)
|
478 |
{ |
479 |
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
|
480 |
return -EINVAL;
|
481 |
} |
482 |
|
483 |
int kvm_arch_remove_sw_breakpoint(CPUState *cs,
|
484 |
struct kvm_sw_breakpoint *bp)
|
485 |
{ |
486 |
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
|
487 |
return -EINVAL;
|
488 |
} |
489 |
|
490 |
void kvm_arch_remove_all_hw_breakpoints(void) |
491 |
{ |
492 |
qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
|
493 |
} |