xref: /kvmtool/arm/aarch64/kvm-cpu.c (revision 1e0c135a3b4592d73020c8e46a21d39c8a076f43)
1*1e0c135aSWill Deacon #include "kvm/kvm-cpu.h"
2*1e0c135aSWill Deacon #include "kvm/kvm.h"
3*1e0c135aSWill Deacon 
4*1e0c135aSWill Deacon #include <asm/ptrace.h>
5*1e0c135aSWill Deacon 
6*1e0c135aSWill Deacon #define COMPAT_PSR_F_BIT	0x00000040
7*1e0c135aSWill Deacon #define COMPAT_PSR_I_BIT	0x00000080
8*1e0c135aSWill Deacon #define COMPAT_PSR_MODE_SVC	0x00000013
9*1e0c135aSWill Deacon 
10*1e0c135aSWill Deacon #define ARM64_CORE_REG(x)	(KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
11*1e0c135aSWill Deacon 				 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
12*1e0c135aSWill Deacon 
13*1e0c135aSWill Deacon static void reset_vcpu_aarch32(struct kvm_cpu *vcpu)
14*1e0c135aSWill Deacon {
15*1e0c135aSWill Deacon 	struct kvm *kvm = vcpu->kvm;
16*1e0c135aSWill Deacon 	struct kvm_one_reg reg;
17*1e0c135aSWill Deacon 	u64 data;
18*1e0c135aSWill Deacon 
19*1e0c135aSWill Deacon 	reg.addr = (u64)&data;
20*1e0c135aSWill Deacon 
21*1e0c135aSWill Deacon 	/* pstate = all interrupts masked */
22*1e0c135aSWill Deacon 	data	= COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT | COMPAT_PSR_MODE_SVC;
23*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pstate);
24*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
25*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (spsr[EL1])");
26*1e0c135aSWill Deacon 
27*1e0c135aSWill Deacon 	/* Secondary cores are stopped awaiting PSCI wakeup */
28*1e0c135aSWill Deacon 	if (vcpu->cpu_id != 0)
29*1e0c135aSWill Deacon 		return;
30*1e0c135aSWill Deacon 
31*1e0c135aSWill Deacon 	/* r0 = 0 */
32*1e0c135aSWill Deacon 	data	= 0;
33*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[0]);
34*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
35*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r0)");
36*1e0c135aSWill Deacon 
37*1e0c135aSWill Deacon 	/* r1 = machine type (-1) */
38*1e0c135aSWill Deacon 	data	= -1;
39*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[1]);
40*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
41*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r1)");
42*1e0c135aSWill Deacon 
43*1e0c135aSWill Deacon 	/* r2 = physical address of the device tree blob */
44*1e0c135aSWill Deacon 	data	= kvm->arch.dtb_guest_start;
45*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[2]);
46*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
47*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r2)");
48*1e0c135aSWill Deacon 
49*1e0c135aSWill Deacon 	/* pc = start of kernel image */
50*1e0c135aSWill Deacon 	data	= kvm->arch.kern_guest_start;
51*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pc);
52*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
53*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (pc)");
54*1e0c135aSWill Deacon }
55*1e0c135aSWill Deacon 
56*1e0c135aSWill Deacon static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
57*1e0c135aSWill Deacon {
58*1e0c135aSWill Deacon 	struct kvm *kvm = vcpu->kvm;
59*1e0c135aSWill Deacon 	struct kvm_one_reg reg;
60*1e0c135aSWill Deacon 	u64 data;
61*1e0c135aSWill Deacon 
62*1e0c135aSWill Deacon 	reg.addr = (u64)&data;
63*1e0c135aSWill Deacon 
64*1e0c135aSWill Deacon 	/* pstate = all interrupts masked */
65*1e0c135aSWill Deacon 	data	= PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL1h;
66*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pstate);
67*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
68*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (spsr[EL1])");
69*1e0c135aSWill Deacon 
70*1e0c135aSWill Deacon 	/* x1...x3 = 0 */
71*1e0c135aSWill Deacon 	data	= 0;
72*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[1]);
73*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
74*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x1)");
75*1e0c135aSWill Deacon 
76*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[2]);
77*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
78*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x2)");
79*1e0c135aSWill Deacon 
80*1e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[3]);
81*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
82*1e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x3)");
83*1e0c135aSWill Deacon 
84*1e0c135aSWill Deacon 	/* Secondary cores are stopped awaiting PSCI wakeup */
85*1e0c135aSWill Deacon 	if (vcpu->cpu_id == 0) {
86*1e0c135aSWill Deacon 		/* x0 = physical address of the device tree blob */
87*1e0c135aSWill Deacon 		data	= kvm->arch.dtb_guest_start;
88*1e0c135aSWill Deacon 		reg.id	= ARM64_CORE_REG(regs.regs[0]);
89*1e0c135aSWill Deacon 		if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
90*1e0c135aSWill Deacon 			die_perror("KVM_SET_ONE_REG failed (x0)");
91*1e0c135aSWill Deacon 
92*1e0c135aSWill Deacon 		/* pc = start of kernel image */
93*1e0c135aSWill Deacon 		data	= kvm->arch.kern_guest_start;
94*1e0c135aSWill Deacon 		reg.id	= ARM64_CORE_REG(regs.pc);
95*1e0c135aSWill Deacon 		if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
96*1e0c135aSWill Deacon 			die_perror("KVM_SET_ONE_REG failed (pc)");
97*1e0c135aSWill Deacon 	}
98*1e0c135aSWill Deacon }
99*1e0c135aSWill Deacon 
100*1e0c135aSWill Deacon void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
101*1e0c135aSWill Deacon {
102*1e0c135aSWill Deacon 	if (vcpu->kvm->cfg.arch.aarch32_guest)
103*1e0c135aSWill Deacon 		return reset_vcpu_aarch32(vcpu);
104*1e0c135aSWill Deacon 	else
105*1e0c135aSWill Deacon 		return reset_vcpu_aarch64(vcpu);
106*1e0c135aSWill Deacon }
107*1e0c135aSWill Deacon 
108*1e0c135aSWill Deacon void kvm_cpu__show_code(struct kvm_cpu *vcpu)
109*1e0c135aSWill Deacon {
110*1e0c135aSWill Deacon 	struct kvm_one_reg reg;
111*1e0c135aSWill Deacon 	unsigned long data;
112*1e0c135aSWill Deacon 
113*1e0c135aSWill Deacon 	reg.addr = (u64)&data;
114*1e0c135aSWill Deacon 
115*1e0c135aSWill Deacon 	printf("*pc:\n");
116*1e0c135aSWill Deacon 	reg.id = ARM64_CORE_REG(regs.pc);
117*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
118*1e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (show_code @ PC)");
119*1e0c135aSWill Deacon 
120*1e0c135aSWill Deacon 	kvm__dump_mem(vcpu->kvm, data, 32);
121*1e0c135aSWill Deacon 	printf("\n");
122*1e0c135aSWill Deacon 
123*1e0c135aSWill Deacon 	printf("*lr:\n");
124*1e0c135aSWill Deacon 	reg.id = ARM64_CORE_REG(regs.regs[30]);
125*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
126*1e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (show_code @ LR)");
127*1e0c135aSWill Deacon 
128*1e0c135aSWill Deacon 	kvm__dump_mem(vcpu->kvm, data, 32);
129*1e0c135aSWill Deacon 	printf("\n");
130*1e0c135aSWill Deacon }
131*1e0c135aSWill Deacon 
132*1e0c135aSWill Deacon void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
133*1e0c135aSWill Deacon {
134*1e0c135aSWill Deacon 	struct kvm_one_reg reg;
135*1e0c135aSWill Deacon 	unsigned long data;
136*1e0c135aSWill Deacon 	int debug_fd = kvm_cpu__get_debug_fd();
137*1e0c135aSWill Deacon 
138*1e0c135aSWill Deacon 	reg.addr = (u64)&data;
139*1e0c135aSWill Deacon 	dprintf(debug_fd, "\n Registers:\n");
140*1e0c135aSWill Deacon 
141*1e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.pc);
142*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
143*1e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (pc)");
144*1e0c135aSWill Deacon 	dprintf(debug_fd, " PC:    0x%lx\n", data);
145*1e0c135aSWill Deacon 
146*1e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.pstate);
147*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
148*1e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (pstate)");
149*1e0c135aSWill Deacon 	dprintf(debug_fd, " PSTATE:    0x%lx\n", data);
150*1e0c135aSWill Deacon 
151*1e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(sp_el1);
152*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
153*1e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (sp_el1)");
154*1e0c135aSWill Deacon 	dprintf(debug_fd, " SP_EL1:    0x%lx\n", data);
155*1e0c135aSWill Deacon 
156*1e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.regs[30]);
157*1e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
158*1e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (lr)");
159*1e0c135aSWill Deacon 	dprintf(debug_fd, " LR:    0x%lx\n", data);
160*1e0c135aSWill Deacon }
161