xref: /kvmtool/arm/aarch64/kvm-cpu.c (revision d06bc640e568ec33bf06f40b62f7d0ac6ce102da)
11e0c135aSWill Deacon #include "kvm/kvm-cpu.h"
21e0c135aSWill Deacon #include "kvm/kvm.h"
31e0c135aSWill Deacon 
41e0c135aSWill Deacon #include <asm/ptrace.h>
51e0c135aSWill Deacon 
61e0c135aSWill Deacon #define COMPAT_PSR_F_BIT	0x00000040
71e0c135aSWill Deacon #define COMPAT_PSR_I_BIT	0x00000080
81e0c135aSWill Deacon #define COMPAT_PSR_MODE_SVC	0x00000013
91e0c135aSWill Deacon 
101e0c135aSWill Deacon #define ARM64_CORE_REG(x)	(KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
111e0c135aSWill Deacon 				 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
121e0c135aSWill Deacon 
13*d06bc640SMarc Zyngier #define ARM64_SYS_REG_SHIFT_MASK(x,n)				\
14*d06bc640SMarc Zyngier 	(((x) << KVM_REG_ARM64_SYSREG_ ## n ## _SHIFT) &	\
15*d06bc640SMarc Zyngier 	 KVM_REG_ARM64_SYSREG_ ## n ## _MASK)
16*d06bc640SMarc Zyngier 
17*d06bc640SMarc Zyngier #define __ARM64_SYS_REG(op0,op1,crn,crm,op2)			\
18*d06bc640SMarc Zyngier 	(KVM_REG_ARM64 | KVM_REG_SIZE_U64		|	\
19*d06bc640SMarc Zyngier 	 KVM_REG_ARM64_SYSREG				|	\
20*d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(op0, OP0)		|	\
21*d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(op1, OP1)		|	\
22*d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(crn, CRN)		|	\
23*d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(crm, CRM)		|	\
24*d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(op2, OP2))
25*d06bc640SMarc Zyngier 
26*d06bc640SMarc Zyngier #define ARM64_SYS_REG(...)	__ARM64_SYS_REG(__VA_ARGS__)
27*d06bc640SMarc Zyngier 
28*d06bc640SMarc Zyngier unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu)
29*d06bc640SMarc Zyngier {
30*d06bc640SMarc Zyngier 	struct kvm_one_reg reg;
31*d06bc640SMarc Zyngier 	u64 mpidr;
32*d06bc640SMarc Zyngier 
33*d06bc640SMarc Zyngier 	reg.id = ARM64_SYS_REG(ARM_CPU_ID, ARM_CPU_ID_MPIDR);
34*d06bc640SMarc Zyngier 	reg.addr = (u64)&mpidr;
35*d06bc640SMarc Zyngier 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
36*d06bc640SMarc Zyngier 		die("KVM_GET_ONE_REG failed (get_mpidr vcpu%ld", vcpu->cpu_id);
37*d06bc640SMarc Zyngier 
38*d06bc640SMarc Zyngier 	return mpidr;
39*d06bc640SMarc Zyngier }
40*d06bc640SMarc Zyngier 
411e0c135aSWill Deacon static void reset_vcpu_aarch32(struct kvm_cpu *vcpu)
421e0c135aSWill Deacon {
431e0c135aSWill Deacon 	struct kvm *kvm = vcpu->kvm;
441e0c135aSWill Deacon 	struct kvm_one_reg reg;
451e0c135aSWill Deacon 	u64 data;
461e0c135aSWill Deacon 
471e0c135aSWill Deacon 	reg.addr = (u64)&data;
481e0c135aSWill Deacon 
491e0c135aSWill Deacon 	/* pstate = all interrupts masked */
501e0c135aSWill Deacon 	data	= COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT | COMPAT_PSR_MODE_SVC;
511e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pstate);
521e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
531e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (spsr[EL1])");
541e0c135aSWill Deacon 
551e0c135aSWill Deacon 	/* Secondary cores are stopped awaiting PSCI wakeup */
561e0c135aSWill Deacon 	if (vcpu->cpu_id != 0)
571e0c135aSWill Deacon 		return;
581e0c135aSWill Deacon 
591e0c135aSWill Deacon 	/* r0 = 0 */
601e0c135aSWill Deacon 	data	= 0;
611e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[0]);
621e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
631e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r0)");
641e0c135aSWill Deacon 
651e0c135aSWill Deacon 	/* r1 = machine type (-1) */
661e0c135aSWill Deacon 	data	= -1;
671e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[1]);
681e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
691e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r1)");
701e0c135aSWill Deacon 
711e0c135aSWill Deacon 	/* r2 = physical address of the device tree blob */
721e0c135aSWill Deacon 	data	= kvm->arch.dtb_guest_start;
731e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[2]);
741e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
751e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r2)");
761e0c135aSWill Deacon 
771e0c135aSWill Deacon 	/* pc = start of kernel image */
781e0c135aSWill Deacon 	data	= kvm->arch.kern_guest_start;
791e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pc);
801e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
811e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (pc)");
821e0c135aSWill Deacon }
831e0c135aSWill Deacon 
841e0c135aSWill Deacon static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
851e0c135aSWill Deacon {
861e0c135aSWill Deacon 	struct kvm *kvm = vcpu->kvm;
871e0c135aSWill Deacon 	struct kvm_one_reg reg;
881e0c135aSWill Deacon 	u64 data;
891e0c135aSWill Deacon 
901e0c135aSWill Deacon 	reg.addr = (u64)&data;
911e0c135aSWill Deacon 
921e0c135aSWill Deacon 	/* pstate = all interrupts masked */
931e0c135aSWill Deacon 	data	= PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL1h;
941e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pstate);
951e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
961e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (spsr[EL1])");
971e0c135aSWill Deacon 
981e0c135aSWill Deacon 	/* x1...x3 = 0 */
991e0c135aSWill Deacon 	data	= 0;
1001e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[1]);
1011e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1021e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x1)");
1031e0c135aSWill Deacon 
1041e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[2]);
1051e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1061e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x2)");
1071e0c135aSWill Deacon 
1081e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[3]);
1091e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1101e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x3)");
1111e0c135aSWill Deacon 
1121e0c135aSWill Deacon 	/* Secondary cores are stopped awaiting PSCI wakeup */
1131e0c135aSWill Deacon 	if (vcpu->cpu_id == 0) {
1141e0c135aSWill Deacon 		/* x0 = physical address of the device tree blob */
1151e0c135aSWill Deacon 		data	= kvm->arch.dtb_guest_start;
1161e0c135aSWill Deacon 		reg.id	= ARM64_CORE_REG(regs.regs[0]);
1171e0c135aSWill Deacon 		if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1181e0c135aSWill Deacon 			die_perror("KVM_SET_ONE_REG failed (x0)");
1191e0c135aSWill Deacon 
1201e0c135aSWill Deacon 		/* pc = start of kernel image */
1211e0c135aSWill Deacon 		data	= kvm->arch.kern_guest_start;
1221e0c135aSWill Deacon 		reg.id	= ARM64_CORE_REG(regs.pc);
1231e0c135aSWill Deacon 		if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1241e0c135aSWill Deacon 			die_perror("KVM_SET_ONE_REG failed (pc)");
1251e0c135aSWill Deacon 	}
1261e0c135aSWill Deacon }
1271e0c135aSWill Deacon 
1281e0c135aSWill Deacon void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
1291e0c135aSWill Deacon {
1301e0c135aSWill Deacon 	if (vcpu->kvm->cfg.arch.aarch32_guest)
1311e0c135aSWill Deacon 		return reset_vcpu_aarch32(vcpu);
1321e0c135aSWill Deacon 	else
1331e0c135aSWill Deacon 		return reset_vcpu_aarch64(vcpu);
1341e0c135aSWill Deacon }
1351e0c135aSWill Deacon 
1361e0c135aSWill Deacon void kvm_cpu__show_code(struct kvm_cpu *vcpu)
1371e0c135aSWill Deacon {
1381e0c135aSWill Deacon 	struct kvm_one_reg reg;
1391e0c135aSWill Deacon 	unsigned long data;
14030c31b66SWill Deacon 	int debug_fd = kvm_cpu__get_debug_fd();
1411e0c135aSWill Deacon 
1421e0c135aSWill Deacon 	reg.addr = (u64)&data;
1431e0c135aSWill Deacon 
14430c31b66SWill Deacon 	dprintf(debug_fd, "\n*pc:\n");
1451e0c135aSWill Deacon 	reg.id = ARM64_CORE_REG(regs.pc);
1461e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
1471e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (show_code @ PC)");
1481e0c135aSWill Deacon 
14930c31b66SWill Deacon 	kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
1501e0c135aSWill Deacon 
15130c31b66SWill Deacon 	dprintf(debug_fd, "\n*lr:\n");
1521e0c135aSWill Deacon 	reg.id = ARM64_CORE_REG(regs.regs[30]);
1531e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
1541e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (show_code @ LR)");
1551e0c135aSWill Deacon 
15630c31b66SWill Deacon 	kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
1571e0c135aSWill Deacon }
1581e0c135aSWill Deacon 
1591e0c135aSWill Deacon void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
1601e0c135aSWill Deacon {
1611e0c135aSWill Deacon 	struct kvm_one_reg reg;
1621e0c135aSWill Deacon 	unsigned long data;
1631e0c135aSWill Deacon 	int debug_fd = kvm_cpu__get_debug_fd();
1641e0c135aSWill Deacon 
1651e0c135aSWill Deacon 	reg.addr = (u64)&data;
1661e0c135aSWill Deacon 	dprintf(debug_fd, "\n Registers:\n");
1671e0c135aSWill Deacon 
1681e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.pc);
1691e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
1701e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (pc)");
1711e0c135aSWill Deacon 	dprintf(debug_fd, " PC:    0x%lx\n", data);
1721e0c135aSWill Deacon 
1731e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.pstate);
1741e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
1751e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (pstate)");
1761e0c135aSWill Deacon 	dprintf(debug_fd, " PSTATE:    0x%lx\n", data);
1771e0c135aSWill Deacon 
1781e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(sp_el1);
1791e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
1801e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (sp_el1)");
1811e0c135aSWill Deacon 	dprintf(debug_fd, " SP_EL1:    0x%lx\n", data);
1821e0c135aSWill Deacon 
1831e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.regs[30]);
1841e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
1851e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (lr)");
1861e0c135aSWill Deacon 	dprintf(debug_fd, " LR:    0x%lx\n", data);
1871e0c135aSWill Deacon }
188