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
431static inline void unset_feature(uint64_t *features, int feature)
432{
433 *features &= ~(1ULL << feature);
434}
435
436bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
437{
438
439
440
441
442
443
444
445 int fdarray[3];
446 uint64_t features = 0;
447
448
449
450
451
452 static const uint32_t cpus_to_try[] = {
453 KVM_ARM_TARGET_AEM_V8,
454 KVM_ARM_TARGET_FOUNDATION_V8,
455 KVM_ARM_TARGET_CORTEX_A57,
456 QEMU_KVM_ARM_TARGET_NONE
457 };
458 struct kvm_vcpu_init init;
459
460 if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
461 return false;
462 }
463
464 ahcc->target = init.target;
465 ahcc->dtb_compatible = "arm,arm-v8";
466
467 kvm_arm_destroy_scratch_host_vcpu(fdarray);
468
469
470
471
472
473 set_feature(&features, ARM_FEATURE_V8);
474 set_feature(&features, ARM_FEATURE_VFP4);
475 set_feature(&features, ARM_FEATURE_NEON);
476 set_feature(&features, ARM_FEATURE_AARCH64);
477 set_feature(&features, ARM_FEATURE_PMU);
478
479 ahcc->features = features;
480
481 return true;
482}
483
484#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
485
486int kvm_arch_init_vcpu(CPUState *cs)
487{
488 int ret;
489 uint64_t mpidr;
490 ARMCPU *cpu = ARM_CPU(cs);
491 CPUARMState *env = &cpu->env;
492
493 if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
494 !object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
495 fprintf(stderr, "KVM is not supported for this guest CPU type\n");
496 return -EINVAL;
497 }
498
499
500 memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
501 if (cpu->start_powered_off) {
502 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
503 }
504 if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
505 cpu->psci_version = 2;
506 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
507 }
508 if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
509 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
510 }
511 if (!kvm_irqchip_in_kernel() ||
512 !kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
513 cpu->has_pmu = false;
514 }
515 if (cpu->has_pmu) {
516 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
517 } else {
518 unset_feature(&env->features, ARM_FEATURE_PMU);
519 }
520
521
522 ret = kvm_arm_vcpu_init(cs);
523 if (ret) {
524 return ret;
525 }
526
527
528
529
530
531
532 ret = kvm_get_one_reg(cs, ARM64_SYS_REG(ARM_CPU_ID_MPIDR), &mpidr);
533 if (ret) {
534 return ret;
535 }
536 cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
537
538 kvm_arm_init_debug(cs);
539
540 return kvm_arm_init_cpreg_list(cpu);
541}
542
543bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
544{
545
546
547
548
549 switch (regidx & KVM_REG_ARM_COPROC_MASK) {
550 case KVM_REG_ARM_CORE:
551 return false;
552 default:
553 return true;
554 }
555}
556
557typedef struct CPRegStateLevel {
558 uint64_t regidx;
559 int level;
560} CPRegStateLevel;
561
562
563
564
565
566
567static const CPRegStateLevel non_runtime_cpregs[] = {
568 { KVM_REG_ARM_TIMER_CNT, KVM_PUT_FULL_STATE },
569};
570
571int kvm_arm_cpreg_level(uint64_t regidx)
572{
573 int i;
574
575 for (i = 0; i < ARRAY_SIZE(non_runtime_cpregs); i++) {
576 const CPRegStateLevel *l = &non_runtime_cpregs[i];
577 if (l->regidx == regidx) {
578 return l->level;
579 }
580 }
581
582 return KVM_PUT_RUNTIME_STATE;
583}
584
585#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
586 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
587
588#define AARCH64_SIMD_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U128 | \
589 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
590
591#define AARCH64_SIMD_CTRL_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U32 | \
592 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
593
594int kvm_arch_put_registers(CPUState *cs, int level)
595{
596 struct kvm_one_reg reg;
597 uint32_t fpr;
598 uint64_t val;
599 int i;
600 int ret;
601 unsigned int el;
602
603 ARMCPU *cpu = ARM_CPU(cs);
604 CPUARMState *env = &cpu->env;
605
606
607
608
609 if (!is_a64(env)) {
610 aarch64_sync_32_to_64(env);
611 }
612
613 for (i = 0; i < 31; i++) {
614 reg.id = AARCH64_CORE_REG(regs.regs[i]);
615 reg.addr = (uintptr_t) &env->xregs[i];
616 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
617 if (ret) {
618 return ret;
619 }
620 }
621
622
623
624
625 aarch64_save_sp(env, 1);
626
627 reg.id = AARCH64_CORE_REG(regs.sp);
628 reg.addr = (uintptr_t) &env->sp_el[0];
629 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
630 if (ret) {
631 return ret;
632 }
633
634 reg.id = AARCH64_CORE_REG(sp_el1);
635 reg.addr = (uintptr_t) &env->sp_el[1];
636 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
637 if (ret) {
638 return ret;
639 }
640
641
642 if (is_a64(env)) {
643 val = pstate_read(env);
644 } else {
645 val = cpsr_read(env);
646 }
647 reg.id = AARCH64_CORE_REG(regs.pstate);
648 reg.addr = (uintptr_t) &val;
649 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
650 if (ret) {
651 return ret;
652 }
653
654 reg.id = AARCH64_CORE_REG(regs.pc);
655 reg.addr = (uintptr_t) &env->pc;
656 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
657 if (ret) {
658 return ret;
659 }
660
661 reg.id = AARCH64_CORE_REG(elr_el1);
662 reg.addr = (uintptr_t) &env->elr_el[1];
663 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
664 if (ret) {
665 return ret;
666 }
667
668
669
670
671
672
673
674 el = arm_current_el(env);
675 if (el > 0 && !is_a64(env)) {
676 i = bank_number(env->uncached_cpsr & CPSR_M);
677 env->banked_spsr[i] = env->spsr;
678 }
679
680
681 for (i = 0; i < KVM_NR_SPSR; i++) {
682 reg.id = AARCH64_CORE_REG(spsr[i]);
683 reg.addr = (uintptr_t) &env->banked_spsr[i + 1];
684 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
685 if (ret) {
686 return ret;
687 }
688 }
689
690
691
692
693 for (i = 0; i < 32; i++) {
694 int rd = i << 1;
695 uint64_t fp_val[2];
696#ifdef HOST_WORDS_BIGENDIAN
697 fp_val[0] = env->vfp.regs[rd + 1];
698 fp_val[1] = env->vfp.regs[rd];
699#else
700 fp_val[1] = env->vfp.regs[rd + 1];
701 fp_val[0] = env->vfp.regs[rd];
702#endif
703 reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
704 reg.addr = (uintptr_t)(&fp_val);
705 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
706 if (ret) {
707 return ret;
708 }
709 }
710
711 reg.addr = (uintptr_t)(&fpr);
712 fpr = vfp_get_fpsr(env);
713 reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
714 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
715 if (ret) {
716 return ret;
717 }
718
719 fpr = vfp_get_fpcr(env);
720 reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
721 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
722 if (ret) {
723 return ret;
724 }
725
726 if (!write_list_to_kvmstate(cpu, level)) {
727 return EINVAL;
728 }
729
730 kvm_arm_sync_mpstate_to_kvm(cpu);
731
732 return ret;
733}
734
735int kvm_arch_get_registers(CPUState *cs)
736{
737 struct kvm_one_reg reg;
738 uint64_t val;
739 uint32_t fpr;
740 unsigned int el;
741 int i;
742 int ret;
743
744 ARMCPU *cpu = ARM_CPU(cs);
745 CPUARMState *env = &cpu->env;
746
747 for (i = 0; i < 31; i++) {
748 reg.id = AARCH64_CORE_REG(regs.regs[i]);
749 reg.addr = (uintptr_t) &env->xregs[i];
750 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
751 if (ret) {
752 return ret;
753 }
754 }
755
756 reg.id = AARCH64_CORE_REG(regs.sp);
757 reg.addr = (uintptr_t) &env->sp_el[0];
758 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
759 if (ret) {
760 return ret;
761 }
762
763 reg.id = AARCH64_CORE_REG(sp_el1);
764 reg.addr = (uintptr_t) &env->sp_el[1];
765 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
766 if (ret) {
767 return ret;
768 }
769
770 reg.id = AARCH64_CORE_REG(regs.pstate);
771 reg.addr = (uintptr_t) &val;
772 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
773 if (ret) {
774 return ret;
775 }
776
777 env->aarch64 = ((val & PSTATE_nRW) == 0);
778 if (is_a64(env)) {
779 pstate_write(env, val);
780 } else {
781 cpsr_write(env, val, 0xffffffff, CPSRWriteRaw);
782 }
783
784
785
786
787 aarch64_restore_sp(env, 1);
788
789 reg.id = AARCH64_CORE_REG(regs.pc);
790 reg.addr = (uintptr_t) &env->pc;
791 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
792 if (ret) {
793 return ret;
794 }
795
796
797
798
799
800
801 if (!is_a64(env)) {
802 aarch64_sync_64_to_32(env);
803 }
804
805 reg.id = AARCH64_CORE_REG(elr_el1);
806 reg.addr = (uintptr_t) &env->elr_el[1];
807 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
808 if (ret) {
809 return ret;
810 }
811
812
813
814
815
816 for (i = 0; i < KVM_NR_SPSR; i++) {
817 reg.id = AARCH64_CORE_REG(spsr[i]);
818 reg.addr = (uintptr_t) &env->banked_spsr[i + 1];
819 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
820 if (ret) {
821 return ret;
822 }
823 }
824
825 el = arm_current_el(env);
826 if (el > 0 && !is_a64(env)) {
827 i = bank_number(env->uncached_cpsr & CPSR_M);
828 env->spsr = env->banked_spsr[i];
829 }
830
831
832
833
834 for (i = 0; i < 32; i++) {
835 uint64_t fp_val[2];
836 reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
837 reg.addr = (uintptr_t)(&fp_val);
838 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
839 if (ret) {
840 return ret;
841 } else {
842 int rd = i << 1;
843#ifdef HOST_WORDS_BIGENDIAN
844 env->vfp.regs[rd + 1] = fp_val[0];
845 env->vfp.regs[rd] = fp_val[1];
846#else
847 env->vfp.regs[rd + 1] = fp_val[1];
848 env->vfp.regs[rd] = fp_val[0];
849#endif
850 }
851 }
852
853 reg.addr = (uintptr_t)(&fpr);
854 reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
855 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
856 if (ret) {
857 return ret;
858 }
859 vfp_set_fpsr(env, fpr);
860
861 reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
862 ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
863 if (ret) {
864 return ret;
865 }
866 vfp_set_fpcr(env, fpr);
867
868 if (!write_kvmstate_to_list(cpu)) {
869 return EINVAL;
870 }
871
872
873
874 write_list_to_cpustate(cpu);
875
876 kvm_arm_sync_mpstate_to_qemu(cpu);
877
878
879 return ret;
880}
881
882
883static const uint32_t brk_insn = 0xd4200000;
884
885int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
886{
887 if (have_guest_debug) {
888 if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
889 cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) {
890 return -EINVAL;
891 }
892 return 0;
893 } else {
894 error_report("guest debug not supported on this kernel");
895 return -EINVAL;
896 }
897}
898
899int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
900{
901 static uint32_t brk;
902
903 if (have_guest_debug) {
904 if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) ||
905 brk != brk_insn ||
906 cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) {
907 return -EINVAL;
908 }
909 return 0;
910 } else {
911 error_report("guest debug not supported on this kernel");
912 return -EINVAL;
913 }
914}
915
916
917
918
919
920
921
922
923bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
924{
925 int hsr_ec = debug_exit->hsr >> ARM_EL_EC_SHIFT;
926 ARMCPU *cpu = ARM_CPU(cs);
927 CPUClass *cc = CPU_GET_CLASS(cs);
928 CPUARMState *env = &cpu->env;
929
930
931 kvm_cpu_synchronize_state(cs);
932
933 switch (hsr_ec) {
934 case EC_SOFTWARESTEP:
935 if (cs->singlestep_enabled) {
936 return true;
937 } else {
938
939
940
941
942 error_report("%s: guest single-step while debugging unsupported"
943 " (%"PRIx64", %"PRIx32")\n",
944 __func__, env->pc, debug_exit->hsr);
945 return false;
946 }
947 break;
948 case EC_AA64_BKPT:
949 if (kvm_find_sw_breakpoint(cs, env->pc)) {
950 return true;
951 }
952 break;
953 case EC_BREAKPOINT:
954 if (find_hw_breakpoint(cs, env->pc)) {
955 return true;
956 }
957 break;
958 case EC_WATCHPOINT:
959 {
960 CPUWatchpoint *wp = find_hw_watchpoint(cs, debug_exit->far);
961 if (wp) {
962 cs->watchpoint_hit = wp;
963 return true;
964 }
965 break;
966 }
967 default:
968 error_report("%s: unhandled debug exit (%"PRIx32", %"PRIx64")\n",
969 __func__, debug_exit->hsr, env->pc);
970 }
971
972
973
974
975
976 cs->exception_index = EXCP_BKPT;
977 env->exception.syndrome = debug_exit->hsr;
978 env->exception.vaddress = debug_exit->far;
979 cc->do_interrupt(cs);
980
981 return false;
982}
983