1
2
3
4
5
6
7
8
9
10
11
12#include "qemu/osdep.h"
13#include <sys/ioctl.h>
14#include <sys/ptrace.h>
15
16#include <linux/elf.h>
17#include <linux/kvm.h>
18
19#include "qemu-common.h"
20#include "cpu.h"
21#include "qemu/timer.h"
22#include "qemu/error-report.h"
23#include "qemu/host-utils.h"
24#include "exec/gdbstub.h"
25#include "sysemu/sysemu.h"
26#include "sysemu/kvm.h"
27#include "kvm_arm.h"
28#include "internals.h"
29#include "hw/arm/arm.h"
30
31static bool have_guest_debug;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48typedef struct {
49 uint64_t bcr;
50 uint64_t bvr;
51} HWBreakpoint;
52
53
54
55
56
57
58typedef struct {
59 uint64_t wcr;
60 uint64_t wvr;
61 CPUWatchpoint details;
62} HWWatchpoint;
63
64
65int max_hw_bps, max_hw_wps;
66GArray *hw_breakpoints, *hw_watchpoints;
67
68#define cur_hw_wps (hw_watchpoints->len)
69#define cur_hw_bps (hw_breakpoints->len)
70#define get_hw_bp(i) (&g_array_index(hw_breakpoints, HWBreakpoint, i))
71#define get_hw_wp(i) (&g_array_index(hw_watchpoints, HWWatchpoint, i))
72
73
74
75
76
77
78
79
80
81static void kvm_arm_init_debug(CPUState *cs)
82{
83 have_guest_debug = kvm_check_extension(cs->kvm_state,
84 KVM_CAP_SET_GUEST_DEBUG);
85
86 max_hw_wps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_WPS);
87 hw_watchpoints = g_array_sized_new(true, true,
88 sizeof(HWWatchpoint), max_hw_wps);
89
90 max_hw_bps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_BPS);
91 hw_breakpoints = g_array_sized_new(true, true,
92 sizeof(HWBreakpoint), max_hw_bps);
93 return;
94}
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119static int insert_hw_breakpoint(target_ulong addr)
120{
121 HWBreakpoint brk = {
122 .bcr = 0x1,
123 .bvr = addr
124 };
125
126 if (cur_hw_bps >= max_hw_bps) {
127 return -ENOBUFS;
128 }
129
130 brk.bcr = deposit32(brk.bcr, 1, 2, 0x3);
131 brk.bcr = deposit32(brk.bcr, 5, 4, 0xf);
132
133 g_array_append_val(hw_breakpoints, brk);
134
135 return 0;
136}
137
138
139
140
141
142
143
144
145static int delete_hw_breakpoint(target_ulong pc)
146{
147 int i;
148 for (i = 0; i < hw_breakpoints->len; i++) {
149 HWBreakpoint *brk = get_hw_bp(i);
150 if (brk->bvr == pc) {
151 g_array_remove_index(hw_breakpoints, i);
152 return 0;
153 }
154 }
155 return -ENOENT;
156}
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190static int insert_hw_watchpoint(target_ulong addr,
191 target_ulong len, int type)
192{
193 HWWatchpoint wp = {
194 .wcr = 1,
195 .wvr = addr & (~0x7ULL),
196 .details = { .vaddr = addr, .len = len }
197 };
198
199 if (cur_hw_wps >= max_hw_wps) {
200 return -ENOBUFS;
201 }
202
203
204
205
206
207 wp.wcr = deposit32(wp.wcr, 1, 2, 3);
208
209 switch (type) {
210 case GDB_WATCHPOINT_READ:
211 wp.wcr = deposit32(wp.wcr, 3, 2, 1);
212 wp.details.flags = BP_MEM_READ;
213 break;
214 case GDB_WATCHPOINT_WRITE:
215 wp.wcr = deposit32(wp.wcr, 3, 2, 2);
216 wp.details.flags = BP_MEM_WRITE;
217 break;
218 case GDB_WATCHPOINT_ACCESS:
219 wp.wcr = deposit32(wp.wcr, 3, 2, 3);
220 wp.details.flags = BP_MEM_ACCESS;
221 break;
222 default:
223 g_assert_not_reached();
224 break;
225 }
226 if (len <= 8) {
227
228 int off = addr & 0x7;
229 int bas = (1 << len) - 1;
230
231 wp.wcr = deposit32(wp.wcr, 5 + off, 8 - off, bas);
232 } else {
233
234 if (is_power_of_2(len)) {
235 int bits = ctz64(len);
236
237 wp.wvr &= ~((1 << bits) - 1);
238 wp.wcr = deposit32(wp.wcr, 24, 4, bits);
239 wp.wcr = deposit32(wp.wcr, 5, 8, 0xff);
240 } else {
241 return -ENOBUFS;
242 }
243 }
244
245 g_array_append_val(hw_watchpoints, wp);
246 return 0;
247}
248
249
250static bool check_watchpoint_in_range(int i, target_ulong addr)
251{
252 HWWatchpoint *wp = get_hw_wp(i);
253 uint64_t addr_top, addr_bottom = wp->wvr;
254 int bas = extract32(wp->wcr, 5, 8);
255 int mask = extract32(wp->wcr, 24, 4);
256
257 if (mask) {
258 addr_top = addr_bottom + (1 << mask);
259 } else {
260
261
262 addr_bottom = addr_bottom + ctz32(bas);
263 addr_top = addr_bottom + clo32(bas);
264 }
265
266 if (addr >= addr_bottom && addr <= addr_top) {
267 return true;
268 }
269
270 return false;
271}
272
273
274
275
276
277
278
279
280static int delete_hw_watchpoint(target_ulong addr,
281 target_ulong len, int type)
282{
283 int i;
284 for (i = 0; i < cur_hw_wps; i++) {
285 if (check_watchpoint_in_range(i, addr)) {
286 g_array_remove_index(hw_watchpoints, i);
287 return 0;
288 }
289 }
290 return -ENOENT;
291}
292
293
294int kvm_arch_insert_hw_breakpoint(target_ulong addr,
295 target_ulong len, int type)
296{
297 switch (type) {
298 case GDB_BREAKPOINT_HW:
299 return insert_hw_breakpoint(addr);
300 break;
301 case GDB_WATCHPOINT_READ:
302 case GDB_WATCHPOINT_WRITE:
303 case GDB_WATCHPOINT_ACCESS:
304 return insert_hw_watchpoint(addr, len, type);
305 default:
306 return -ENOSYS;
307 }
308}
309
310int kvm_arch_remove_hw_breakpoint(target_ulong addr,
311 target_ulong len, int type)
312{
313 switch (type) {
314 case GDB_BREAKPOINT_HW:
315 return delete_hw_breakpoint(addr);
316 break;
317 case GDB_WATCHPOINT_READ:
318 case GDB_WATCHPOINT_WRITE:
319 case GDB_WATCHPOINT_ACCESS:
320 return delete_hw_watchpoint(addr, len, type);
321 default:
322 return -ENOSYS;
323 }
324}
325
326
327void kvm_arch_remove_all_hw_breakpoints(void)
328{
329 if (cur_hw_wps > 0) {
330 g_array_remove_range(hw_watchpoints, 0, cur_hw_wps);
331 }
332 if (cur_hw_bps > 0) {
333 g_array_remove_range(hw_breakpoints, 0, cur_hw_bps);
334 }
335}
336
337void kvm_arm_copy_hw_debug_data(struct kvm_guest_debug_arch *ptr)
338{
339 int i;
340 memset(ptr, 0, sizeof(struct kvm_guest_debug_arch));
341
342 for (i = 0; i < max_hw_wps; i++) {
343 HWWatchpoint *wp = get_hw_wp(i);
344 ptr->dbg_wcr[i] = wp->wcr;
345 ptr->dbg_wvr[i] = wp->wvr;
346 }
347 for (i = 0; i < max_hw_bps; i++) {
348 HWBreakpoint *bp = get_hw_bp(i);
349 ptr->dbg_bcr[i] = bp->bcr;
350 ptr->dbg_bvr[i] = bp->bvr;
351 }
352}
353
354bool kvm_arm_hw_debug_active(CPUState *cs)
355{
356 return ((cur_hw_wps > 0) || (cur_hw_bps > 0));
357}
358
359static bool find_hw_breakpoint(CPUState *cpu, target_ulong pc)
360{
361 int i;
362
363 for (i = 0; i < cur_hw_bps; i++) {
364 HWBreakpoint *bp = get_hw_bp(i);
365 if (bp->bvr == pc) {
366 return true;
367 }
368 }
369 return false;
370}
371
372static CPUWatchpoint *find_hw_watchpoint(CPUState *cpu, target_ulong addr)
373{
374 int i;
375
376 for (i = 0; i < cur_hw_wps; i++) {
377 if (check_watchpoint_in_range(i, addr)) {
378 return &get_hw_wp(i)->details;
379 }
380 }
381 return NULL;
382}
383
384static bool kvm_arm_pmu_support_ctrl(CPUState *cs, struct kvm_device_attr *attr)
385{
386 return kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr) == 0;
387}
388
389int kvm_arm_pmu_create(CPUState *cs, int irq)
390{
391 int err;
392
393 struct kvm_device_attr attr = {
394 .group = KVM_ARM_VCPU_PMU_V3_CTRL,
395 .addr = (intptr_t)&irq,
396 .attr = KVM_ARM_VCPU_PMU_V3_IRQ,
397 .flags = 0,
398 };
399
400 if (!kvm_arm_pmu_support_ctrl(cs, &attr)) {
401 return 0;
402 }
403
404 err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
405 if (err < 0) {
406 fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
407 strerror(-err));
408 abort();
409 }
410
411 attr.group = KVM_ARM_VCPU_PMU_V3_CTRL;
412 attr.attr = KVM_ARM_VCPU_PMU_V3_INIT;
413 attr.addr = 0;
414 attr.flags = 0;
415
416 err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
417 if (err < 0) {
418 fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
419 strerror(-err));
420 abort();
421 }
422
423 return 1;
424}
425
426static inline void set_feature(uint64_t *features, int feature)
427{
428 *features |= 1ULL << feature;
429}
430
431bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
432{
433
434
435
436
437
438
439
440 int fdarray[3];
441 uint64_t features = 0;
442
443
444
445
446
447 static const uint32_t cpus_to_try[] = {
448 KVM_ARM_TARGET_AEM_V8,
449 KVM_ARM_TARGET_FOUNDATION_V8,
450 KVM_ARM_TARGET_CORTEX_A57,
451 QEMU_KVM_ARM_TARGET_NONE
452 };
453 struct kvm_vcpu_init init;
454
455 if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
456 return false;
457 }
458
459 ahcc->target = init.target;
460 ahcc->dtb_compatible = "arm,arm-v8";
461
462 kvm_arm_destroy_scratch_host_vcpu(fdarray);
463
464
465
466
467
468 set_feature(&features, ARM_FEATURE_V8);
469 set_feature(&features, ARM_FEATURE_VFP4);
470 set_feature(&features, ARM_FEATURE_NEON);
471 set_feature(&features, ARM_FEATURE_AARCH64);
472
473 ahcc->features = features;
474
475 return true;
476}
477
478#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
479
480int kvm_arch_init_vcpu(CPUState *cs)
481{
482 int ret;
483 uint64_t mpidr;
484 ARMCPU *cpu = ARM_CPU(cs);
485
486 if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
487 !object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
488 fprintf(stderr, "KVM is not supported for this guest CPU type\n");
489 return -EINVAL;
490 }
491
492
493 memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
494 if (cpu->start_powered_off) {
495 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
496 }
497 if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
498 cpu->psci_version = 2;
499 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
500 }
501 if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
502 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
503 }
504 if (kvm_irqchip_in_kernel() &&
505 kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
506 cpu->has_pmu = true;
507 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
508 }
509
510
511 ret = kvm_arm_vcpu_init(cs);
512 if (ret) {
513 return ret;
514 }
515
516
517
518
519
520
521 ret = kvm_get_one_reg(cs, ARM64_SYS_REG(ARM_CPU_ID_MPIDR), &mpidr);
522 if (ret) {
523 return ret;
524 }
525 cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
526
527 kvm_arm_init_debug(cs);
528
529 return kvm_arm_init_cpreg_list(cpu);
530}
531
532bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
533{
534
535
536
537
538 switch (regidx & KVM_REG_ARM_COPROC_MASK) {
539 case KVM_REG_ARM_CORE:
540 return false;
541 default:
542 return true;
543 }
544}
545
546typedef struct CPRegStateLevel {
547 uint64_t regidx;
548 int level;
549} CPRegStateLevel;
550
551
552
553
554
555
556static const CPRegStateLevel non_runtime_cpregs[] = {
557 { KVM_REG_ARM_TIMER_CNT, KVM_PUT_FULL_STATE },
558};
559
560int kvm_arm_cpreg_level(uint64_t regidx)
561{
562 int i;
563
564 for (i = 0; i < ARRAY_SIZE(non_runtime_cpregs); i++) {
565 const CPRegStateLevel *l = &non_runtime_cpregs[i];
566 if (l->regidx == regidx) {
567 return l->level;
568 }
569 }
570
571 return KVM_PUT_RUNTIME_STATE;
572}
573
574#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
575 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
576
577#define AARCH64_SIMD_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U128 | \
578 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
579
580#define AARCH64_SIMD_CTRL_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U32 | \
581 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
582
583int kvm_arch_put_registers(CPUState *cs, int level)
584{
585 struct kvm_one_reg reg;
586 uint32_t fpr;
587 uint64_t val;
588 int i;
589 int ret;
590 unsigned int el;
591
592 ARMCPU *cpu = ARM_CPU(cs);
593 CPUARMState *env = &cpu->env;
594
595
596
597
598 if (!is_a64(env)) {
599 aarch64_sync_32_to_64(env);
600 }
601
602 for (i = 0; i < 31; i++) {
603 reg.id = AARCH64_CORE_REG(regs.regs[i]);
604 reg.addr = (uintptr_t) &env->xregs[i];
605 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
606 if (ret) {
607 return ret;
608 }
609 }
610
611
612
613
614 aarch64_save_sp(env, 1);
615
616 reg.id = AARCH64_CORE_REG(regs.sp);
617 reg.addr = (uintptr_t) &env->sp_el[0];
618 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
619 if (ret) {
620 return ret;
621 }
622
623 reg.id = AARCH64_CORE_REG(sp_el1);
624 reg.addr = (uintptr_t) &env->sp_el[1];
625 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
626 if (ret) {
627 return ret;
628 }
629
630
631 if (is_a64(env)) {
632 val = pstate_read(env);
633 } else {
634 val = cpsr_read(env);
635 }
636 reg.id = AARCH64_CORE_REG(regs.pstate);
637 reg.addr = (uintptr_t) &val;
638 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
639 if (ret) {
640 return ret;
641 }
642
643 reg.id = AARCH64_CORE_REG(regs.pc);
644 reg.addr = (uintptr_t) &env->pc;
645 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
646 if (ret) {
647 return ret;
648 }
649
650 reg.id = AARCH64_CORE_REG(elr_el1);
651 reg.addr = (uintptr_t) &env->elr_el[1];
652 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
653 if (ret) {
654 return ret;
655 }
656
657
658
659
660
661
662
663 el = arm_current_el(env);
664 if (el > 0 && !is_a64(env)) {
665 i = bank_number(env->uncached_cpsr & CPSR_M);
666 env->banked_spsr[i] = env->spsr;
667 }
668
669
670 for (i = 0; i < KVM_NR_SPSR; i++) {
671 reg.id = AARCH64_CORE_REG(spsr[i]);
672 reg.addr = (uintptr_t) &env->banked_spsr[i + 1];
673 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
674 if (ret) {
675 return ret;
676 }
677 }
678
679
680
681
682 for (i = 0; i < 32; i++) {
683 int rd = i << 1;
684 uint64_t fp_val[2];
685#ifdef HOST_WORDS_BIGENDIAN
686 fp_val[0] = env->vfp.regs[rd + 1];
687 fp_val[1] = env->vfp.regs[rd];
688#else
689 fp_val[1] = env->vfp.regs[rd + 1];
690 fp_val[0] = env->vfp.regs[rd];
691#endif
692 reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
693 reg.addr = (uintptr_t)(&fp_val);
694 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
695 if (ret) {
696 return ret;
697 }
698 }
699
700 reg.addr = (uintptr_t)(&fpr);
701 fpr = vfp_get_fpsr(env);
702 reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
703 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
704 if (ret) {
705 return ret;
706 }
707
708 fpr = vfp_get_fpcr(env);
709 reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
710 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
711 if (ret) {
712 return ret;
713 }
714
715 if (!write_list_to_kvmstate(cpu, level)) {
716 return EINVAL;
717 }
718
719 kvm_arm_sync_mpstate_to_kvm(cpu);
720
721 return ret;
722}
723
724int kvm_arch_get_registers(CPUState *cs)
725{
726 struct kvm_one_reg reg;
727 uint64_t val;
728 uint32_t fpr;
729 unsigned int el;
730 int i;
731 int ret;
732
733 ARMCPU *cpu = ARM_CPU(cs);
734 CPUARMState *env = &cpu->env;
735
736 for (i = 0; i < 31; i++) {
737 reg.id = AARCH64_CORE_REG(regs.regs[i]);
738 reg.addr = (uintptr_t) &env->xregs[i];
739 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
740 if (ret) {
741 return ret;
742 }
743 }
744
745 reg.id = AARCH64_CORE_REG(regs.sp);
746 reg.addr = (uintptr_t) &env->sp_el[0];
747 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
748 if (ret) {
749 return ret;
750 }
751
752 reg.id = AARCH64_CORE_REG(sp_el1);
753 reg.addr = (uintptr_t) &env->sp_el[1];
754 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
755 if (ret) {
756 return ret;
757 }
758
759 reg.id = AARCH64_CORE_REG(regs.pstate);
760 reg.addr = (uintptr_t) &val;
761 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
762 if (ret) {
763 return ret;
764 }
765
766 env->aarch64 = ((val & PSTATE_nRW) == 0);
767 if (is_a64(env)) {
768 pstate_write(env, val);
769 } else {
770 cpsr_write(env, val, 0xffffffff, CPSRWriteRaw);
771 }
772
773
774
775
776 aarch64_restore_sp(env, 1);
777
778 reg.id = AARCH64_CORE_REG(regs.pc);
779 reg.addr = (uintptr_t) &env->pc;
780 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
781 if (ret) {
782 return ret;
783 }
784
785
786
787
788
789
790 if (!is_a64(env)) {
791 aarch64_sync_64_to_32(env);
792 }
793
794 reg.id = AARCH64_CORE_REG(elr_el1);
795 reg.addr = (uintptr_t) &env->elr_el[1];
796 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
797 if (ret) {
798 return ret;
799 }
800
801
802
803
804
805 for (i = 0; i < KVM_NR_SPSR; i++) {
806 reg.id = AARCH64_CORE_REG(spsr[i]);
807 reg.addr = (uintptr_t) &env->banked_spsr[i + 1];
808 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
809 if (ret) {
810 return ret;
811 }
812 }
813
814 el = arm_current_el(env);
815 if (el > 0 && !is_a64(env)) {
816 i = bank_number(env->uncached_cpsr & CPSR_M);
817 env->spsr = env->banked_spsr[i];
818 }
819
820
821
822
823 for (i = 0; i < 32; i++) {
824 uint64_t fp_val[2];
825 reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
826 reg.addr = (uintptr_t)(&fp_val);
827 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
828 if (ret) {
829 return ret;
830 } else {
831 int rd = i << 1;
832#ifdef HOST_WORDS_BIGENDIAN
833 env->vfp.regs[rd + 1] = fp_val[0];
834 env->vfp.regs[rd] = fp_val[1];
835#else
836 env->vfp.regs[rd + 1] = fp_val[1];
837 env->vfp.regs[rd] = fp_val[0];
838#endif
839 }
840 }
841
842 reg.addr = (uintptr_t)(&fpr);
843 reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
844 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
845 if (ret) {
846 return ret;
847 }
848 vfp_set_fpsr(env, fpr);
849
850 reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
851 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
852 if (ret) {
853 return ret;
854 }
855 vfp_set_fpcr(env, fpr);
856
857 if (!write_kvmstate_to_list(cpu)) {
858 return EINVAL;
859 }
860
861
862
863 write_list_to_cpustate(cpu);
864
865 kvm_arm_sync_mpstate_to_qemu(cpu);
866
867
868 return ret;
869}
870
871
872static const uint32_t brk_insn = 0xd4200000;
873
874int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
875{
876 if (have_guest_debug) {
877 if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
878 cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) {
879 return -EINVAL;
880 }
881 return 0;
882 } else {
883 error_report("guest debug not supported on this kernel");
884 return -EINVAL;
885 }
886}
887
888int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
889{
890 static uint32_t brk;
891
892 if (have_guest_debug) {
893 if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) ||
894 brk != brk_insn ||
895 cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) {
896 return -EINVAL;
897 }
898 return 0;
899 } else {
900 error_report("guest debug not supported on this kernel");
901 return -EINVAL;
902 }
903}
904
905
906
907
908
909
910
911
912bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
913{
914 int hsr_ec = debug_exit->hsr >> ARM_EL_EC_SHIFT;
915 ARMCPU *cpu = ARM_CPU(cs);
916 CPUClass *cc = CPU_GET_CLASS(cs);
917 CPUARMState *env = &cpu->env;
918
919
920 kvm_cpu_synchronize_state(cs);
921
922 switch (hsr_ec) {
923 case EC_SOFTWARESTEP:
924 if (cs->singlestep_enabled) {
925 return true;
926 } else {
927
928
929
930
931 error_report("%s: guest single-step while debugging unsupported"
932 " (%"PRIx64", %"PRIx32")\n",
933 __func__, env->pc, debug_exit->hsr);
934 return false;
935 }
936 break;
937 case EC_AA64_BKPT:
938 if (kvm_find_sw_breakpoint(cs, env->pc)) {
939 return true;
940 }
941 break;
942 case EC_BREAKPOINT:
943 if (find_hw_breakpoint(cs, env->pc)) {
944 return true;
945 }
946 break;
947 case EC_WATCHPOINT:
948 {
949 CPUWatchpoint *wp = find_hw_watchpoint(cs, debug_exit->far);
950 if (wp) {
951 cs->watchpoint_hit = wp;
952 return true;
953 }
954 break;
955 }
956 default:
957 error_report("%s: unhandled debug exit (%"PRIx32", %"PRIx64")\n",
958 __func__, debug_exit->hsr, env->pc);
959 }
960
961
962
963
964
965 cs->exception_index = EXCP_BKPT;
966 env->exception.syndrome = debug_exit->hsr;
967 env->exception.vaddress = debug_exit->far;
968 cc->do_interrupt(cs);
969
970 return false;
971}
972