1 #include "kvm/kvm-cpu.h"
2 #include "kvm/kvm.h"
3 #include "kvm/virtio.h"
4
5 #include <asm/ptrace.h>
6
7 #define ARM_CORE_REG(x) (KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE | \
8 KVM_REG_ARM_CORE_REG(x))
9
kvm_cpu__get_vcpu_mpidr(struct kvm_cpu * vcpu)10 unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu)
11 {
12 struct kvm_one_reg reg;
13 u32 mpidr;
14
15 reg.id = ARM_CP15_REG32(ARM_CPU_ID, ARM_CPU_ID_MPIDR);
16 reg.addr = (u64)(unsigned long)&mpidr;
17 if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
18 die("KVM_GET_ONE_REG failed (get_mpidr vcpu%ld", vcpu->cpu_id);
19
20 return mpidr;
21 }
22
kvm_cpu__reset_vcpu(struct kvm_cpu * vcpu)23 void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
24 {
25 struct kvm *kvm = vcpu->kvm;
26 struct kvm_one_reg reg;
27 u32 data;
28
29 /* Who said future-proofing was a good idea? */
30 reg.addr = (u64)(unsigned long)&data;
31
32 /* cpsr = IRQs/FIQs masked */
33 data = PSR_I_BIT | PSR_F_BIT | SVC_MODE;
34 reg.id = ARM_CORE_REG(usr_regs.ARM_cpsr);
35 if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
36 die_perror("KVM_SET_ONE_REG failed (cpsr)");
37
38 /* Secondary cores are stopped awaiting PSCI wakeup */
39 if (vcpu->cpu_id != 0)
40 return;
41
42 /* r0 = 0 */
43 data = 0;
44 reg.id = ARM_CORE_REG(usr_regs.ARM_r0);
45 if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
46 die_perror("KVM_SET_ONE_REG failed (r0)");
47
48 /* r1 = machine type (-1) */
49 data = -1;
50 reg.id = ARM_CORE_REG(usr_regs.ARM_r1);
51 if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
52 die_perror("KVM_SET_ONE_REG failed (r1)");
53
54 /* r2 = physical address of the device tree blob */
55 data = kvm->arch.dtb_guest_start;
56 reg.id = ARM_CORE_REG(usr_regs.ARM_r2);
57 if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
58 die_perror("KVM_SET_ONE_REG failed (r2)");
59
60 /* pc = start of kernel image */
61 data = kvm->arch.kern_guest_start;
62 reg.id = ARM_CORE_REG(usr_regs.ARM_pc);
63 if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
64 die_perror("KVM_SET_ONE_REG failed (pc)");
65 }
66
kvm_cpu__get_endianness(struct kvm_cpu * vcpu)67 int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
68 {
69 struct kvm_one_reg reg;
70 u32 data;
71
72 reg.id = ARM_CORE_REG(usr_regs.ARM_cpsr);
73 reg.addr = (u64)(unsigned long)&data;
74 if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
75 die("KVM_GET_ONE_REG failed (cpsr)");
76
77 return (data & PSR_E_BIT) ? VIRTIO_ENDIAN_BE : VIRTIO_ENDIAN_LE;
78 }
79
kvm_cpu__show_code(struct kvm_cpu * vcpu)80 void kvm_cpu__show_code(struct kvm_cpu *vcpu)
81 {
82 struct kvm_one_reg reg;
83 u32 data;
84 int debug_fd = kvm_cpu__get_debug_fd();
85
86 reg.addr = (u64)(unsigned long)&data;
87
88 dprintf(debug_fd, "\n*pc:\n");
89 reg.id = ARM_CORE_REG(usr_regs.ARM_pc);
90 if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
91 die("KVM_GET_ONE_REG failed (show_code @ PC)");
92
93 kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
94
95 dprintf(debug_fd, "\n*lr (svc):\n");
96 reg.id = ARM_CORE_REG(svc_regs[1]);
97 if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
98 die("KVM_GET_ONE_REG failed (show_code @ LR_svc)");
99 data &= ~0x1;
100
101 kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
102 }
103
kvm_cpu__show_registers(struct kvm_cpu * vcpu)104 void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
105 {
106 struct kvm_one_reg reg;
107 u32 data;
108 int debug_fd = kvm_cpu__get_debug_fd();
109
110 reg.addr = (u64)(unsigned long)&data;
111 dprintf(debug_fd, "\n Registers:\n");
112
113 reg.id = ARM_CORE_REG(usr_regs.ARM_pc);
114 if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
115 die("KVM_GET_ONE_REG failed (pc)");
116 dprintf(debug_fd, " PC: 0x%x\n", data);
117
118 reg.id = ARM_CORE_REG(usr_regs.ARM_cpsr);
119 if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
120 die("KVM_GET_ONE_REG failed (cpsr)");
121 dprintf(debug_fd, " CPSR: 0x%x\n", data);
122
123 reg.id = ARM_CORE_REG(svc_regs[0]);
124 if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
125 die("KVM_GET_ONE_REG failed (SP_svc)");
126 dprintf(debug_fd, " SP_svc: 0x%x\n", data);
127
128 reg.id = ARM_CORE_REG(svc_regs[1]);
129 if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
130 die("KVM_GET_ONE_REG failed (LR_svc)");
131 dprintf(debug_fd, " LR_svc: 0x%x\n", data);
132 }
133