xref: /kvmtool/arm/aarch32/kvm-cpu.c (revision 91eaedaea9b067e98fd4e8dc81d0e12e71267e3a)
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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &reg) < 0)
130 		die("KVM_GET_ONE_REG failed (LR_svc)");
131 	dprintf(debug_fd, " LR_svc:  0x%x\n", data);
132 }
133