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