xref: /kvmtool/arm/aarch64/kvm-cpu.c (revision fc9d8ec3e459b744c012b9c82924aa397099ab19)
11e0c135aSWill Deacon #include "kvm/kvm-cpu.h"
21e0c135aSWill Deacon #include "kvm/kvm.h"
3*fc9d8ec3SMarc Zyngier #include "kvm/virtio.h"
41e0c135aSWill Deacon 
51e0c135aSWill Deacon #include <asm/ptrace.h>
61e0c135aSWill Deacon 
71e0c135aSWill Deacon #define COMPAT_PSR_F_BIT	0x00000040
81e0c135aSWill Deacon #define COMPAT_PSR_I_BIT	0x00000080
9*fc9d8ec3SMarc Zyngier #define COMPAT_PSR_E_BIT	0x00000200
101e0c135aSWill Deacon #define COMPAT_PSR_MODE_SVC	0x00000013
111e0c135aSWill Deacon 
12*fc9d8ec3SMarc Zyngier #define SCTLR_EL1_E0E_MASK	(1 << 24)
13*fc9d8ec3SMarc Zyngier #define SCTLR_EL1_EE_MASK	(1 << 25)
14*fc9d8ec3SMarc Zyngier 
151e0c135aSWill Deacon #define ARM64_CORE_REG(x)	(KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
161e0c135aSWill Deacon 				 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
171e0c135aSWill Deacon 
18d06bc640SMarc Zyngier #define ARM64_SYS_REG_SHIFT_MASK(x,n)				\
19d06bc640SMarc Zyngier 	(((x) << KVM_REG_ARM64_SYSREG_ ## n ## _SHIFT) &	\
20d06bc640SMarc Zyngier 	 KVM_REG_ARM64_SYSREG_ ## n ## _MASK)
21d06bc640SMarc Zyngier 
22d06bc640SMarc Zyngier #define __ARM64_SYS_REG(op0,op1,crn,crm,op2)			\
23d06bc640SMarc Zyngier 	(KVM_REG_ARM64 | KVM_REG_SIZE_U64		|	\
24d06bc640SMarc Zyngier 	 KVM_REG_ARM64_SYSREG				|	\
25d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(op0, OP0)		|	\
26d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(op1, OP1)		|	\
27d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(crn, CRN)		|	\
28d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(crm, CRM)		|	\
29d06bc640SMarc Zyngier 	 ARM64_SYS_REG_SHIFT_MASK(op2, OP2))
30d06bc640SMarc Zyngier 
31d06bc640SMarc Zyngier #define ARM64_SYS_REG(...)	__ARM64_SYS_REG(__VA_ARGS__)
32d06bc640SMarc Zyngier 
33d06bc640SMarc Zyngier unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu)
34d06bc640SMarc Zyngier {
35d06bc640SMarc Zyngier 	struct kvm_one_reg reg;
36d06bc640SMarc Zyngier 	u64 mpidr;
37d06bc640SMarc Zyngier 
38d06bc640SMarc Zyngier 	reg.id = ARM64_SYS_REG(ARM_CPU_ID, ARM_CPU_ID_MPIDR);
39d06bc640SMarc Zyngier 	reg.addr = (u64)&mpidr;
40d06bc640SMarc Zyngier 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
41d06bc640SMarc Zyngier 		die("KVM_GET_ONE_REG failed (get_mpidr vcpu%ld", vcpu->cpu_id);
42d06bc640SMarc Zyngier 
43d06bc640SMarc Zyngier 	return mpidr;
44d06bc640SMarc Zyngier }
45d06bc640SMarc Zyngier 
461e0c135aSWill Deacon static void reset_vcpu_aarch32(struct kvm_cpu *vcpu)
471e0c135aSWill Deacon {
481e0c135aSWill Deacon 	struct kvm *kvm = vcpu->kvm;
491e0c135aSWill Deacon 	struct kvm_one_reg reg;
501e0c135aSWill Deacon 	u64 data;
511e0c135aSWill Deacon 
521e0c135aSWill Deacon 	reg.addr = (u64)&data;
531e0c135aSWill Deacon 
541e0c135aSWill Deacon 	/* pstate = all interrupts masked */
551e0c135aSWill Deacon 	data	= COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT | COMPAT_PSR_MODE_SVC;
561e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pstate);
571e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
581e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (spsr[EL1])");
591e0c135aSWill Deacon 
601e0c135aSWill Deacon 	/* Secondary cores are stopped awaiting PSCI wakeup */
611e0c135aSWill Deacon 	if (vcpu->cpu_id != 0)
621e0c135aSWill Deacon 		return;
631e0c135aSWill Deacon 
641e0c135aSWill Deacon 	/* r0 = 0 */
651e0c135aSWill Deacon 	data	= 0;
661e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[0]);
671e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
681e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r0)");
691e0c135aSWill Deacon 
701e0c135aSWill Deacon 	/* r1 = machine type (-1) */
711e0c135aSWill Deacon 	data	= -1;
721e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[1]);
731e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
741e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r1)");
751e0c135aSWill Deacon 
761e0c135aSWill Deacon 	/* r2 = physical address of the device tree blob */
771e0c135aSWill Deacon 	data	= kvm->arch.dtb_guest_start;
781e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[2]);
791e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
801e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (r2)");
811e0c135aSWill Deacon 
821e0c135aSWill Deacon 	/* pc = start of kernel image */
831e0c135aSWill Deacon 	data	= kvm->arch.kern_guest_start;
841e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pc);
851e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
861e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (pc)");
871e0c135aSWill Deacon }
881e0c135aSWill Deacon 
891e0c135aSWill Deacon static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
901e0c135aSWill Deacon {
911e0c135aSWill Deacon 	struct kvm *kvm = vcpu->kvm;
921e0c135aSWill Deacon 	struct kvm_one_reg reg;
931e0c135aSWill Deacon 	u64 data;
941e0c135aSWill Deacon 
951e0c135aSWill Deacon 	reg.addr = (u64)&data;
961e0c135aSWill Deacon 
971e0c135aSWill Deacon 	/* pstate = all interrupts masked */
981e0c135aSWill Deacon 	data	= PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL1h;
991e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.pstate);
1001e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1011e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (spsr[EL1])");
1021e0c135aSWill Deacon 
1031e0c135aSWill Deacon 	/* x1...x3 = 0 */
1041e0c135aSWill Deacon 	data	= 0;
1051e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[1]);
1061e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1071e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x1)");
1081e0c135aSWill Deacon 
1091e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[2]);
1101e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1111e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x2)");
1121e0c135aSWill Deacon 
1131e0c135aSWill Deacon 	reg.id	= ARM64_CORE_REG(regs.regs[3]);
1141e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1151e0c135aSWill Deacon 		die_perror("KVM_SET_ONE_REG failed (x3)");
1161e0c135aSWill Deacon 
1171e0c135aSWill Deacon 	/* Secondary cores are stopped awaiting PSCI wakeup */
1181e0c135aSWill Deacon 	if (vcpu->cpu_id == 0) {
1191e0c135aSWill Deacon 		/* x0 = physical address of the device tree blob */
1201e0c135aSWill Deacon 		data	= kvm->arch.dtb_guest_start;
1211e0c135aSWill Deacon 		reg.id	= ARM64_CORE_REG(regs.regs[0]);
1221e0c135aSWill Deacon 		if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1231e0c135aSWill Deacon 			die_perror("KVM_SET_ONE_REG failed (x0)");
1241e0c135aSWill Deacon 
1251e0c135aSWill Deacon 		/* pc = start of kernel image */
1261e0c135aSWill Deacon 		data	= kvm->arch.kern_guest_start;
1271e0c135aSWill Deacon 		reg.id	= ARM64_CORE_REG(regs.pc);
1281e0c135aSWill Deacon 		if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
1291e0c135aSWill Deacon 			die_perror("KVM_SET_ONE_REG failed (pc)");
1301e0c135aSWill Deacon 	}
1311e0c135aSWill Deacon }
1321e0c135aSWill Deacon 
1331e0c135aSWill Deacon void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
1341e0c135aSWill Deacon {
1351e0c135aSWill Deacon 	if (vcpu->kvm->cfg.arch.aarch32_guest)
1361e0c135aSWill Deacon 		return reset_vcpu_aarch32(vcpu);
1371e0c135aSWill Deacon 	else
1381e0c135aSWill Deacon 		return reset_vcpu_aarch64(vcpu);
1391e0c135aSWill Deacon }
1401e0c135aSWill Deacon 
141*fc9d8ec3SMarc Zyngier int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
142*fc9d8ec3SMarc Zyngier {
143*fc9d8ec3SMarc Zyngier 	struct kvm_one_reg reg;
144*fc9d8ec3SMarc Zyngier 	u64 psr;
145*fc9d8ec3SMarc Zyngier 	u64 sctlr;
146*fc9d8ec3SMarc Zyngier 
147*fc9d8ec3SMarc Zyngier 	/*
148*fc9d8ec3SMarc Zyngier 	 * Quoting the definition given by Peter Maydell:
149*fc9d8ec3SMarc Zyngier 	 *
150*fc9d8ec3SMarc Zyngier 	 * "Endianness of the CPU which does the virtio reset at the
151*fc9d8ec3SMarc Zyngier 	 * point when it does that reset"
152*fc9d8ec3SMarc Zyngier 	 *
153*fc9d8ec3SMarc Zyngier 	 * We first check for an AArch32 guest: its endianness can
154*fc9d8ec3SMarc Zyngier 	 * change when using SETEND, which affects the CPSR.E bit.
155*fc9d8ec3SMarc Zyngier 	 *
156*fc9d8ec3SMarc Zyngier 	 * If we're AArch64, use SCTLR_EL1.E0E if access comes from
157*fc9d8ec3SMarc Zyngier 	 * EL0, and SCTLR_EL1.EE if access comes from EL1.
158*fc9d8ec3SMarc Zyngier 	 */
159*fc9d8ec3SMarc Zyngier 	reg.id = ARM64_CORE_REG(regs.pstate);
160*fc9d8ec3SMarc Zyngier 	reg.addr = (u64)&psr;
161*fc9d8ec3SMarc Zyngier 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
162*fc9d8ec3SMarc Zyngier 		die("KVM_GET_ONE_REG failed (spsr[EL1])");
163*fc9d8ec3SMarc Zyngier 
164*fc9d8ec3SMarc Zyngier 	if (psr & PSR_MODE32_BIT)
165*fc9d8ec3SMarc Zyngier 		return (psr & COMPAT_PSR_E_BIT) ? VIRTIO_ENDIAN_BE : VIRTIO_ENDIAN_LE;
166*fc9d8ec3SMarc Zyngier 
167*fc9d8ec3SMarc Zyngier 	reg.id = ARM64_SYS_REG(ARM_CPU_CTRL, ARM_CPU_CTRL_SCTLR_EL1);
168*fc9d8ec3SMarc Zyngier 	reg.addr = (u64)&sctlr;
169*fc9d8ec3SMarc Zyngier 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
170*fc9d8ec3SMarc Zyngier 		die("KVM_GET_ONE_REG failed (SCTLR_EL1)");
171*fc9d8ec3SMarc Zyngier 
172*fc9d8ec3SMarc Zyngier 	if ((psr & PSR_MODE_MASK) == PSR_MODE_EL0t)
173*fc9d8ec3SMarc Zyngier 		sctlr &= SCTLR_EL1_E0E_MASK;
174*fc9d8ec3SMarc Zyngier 	else
175*fc9d8ec3SMarc Zyngier 		sctlr &= SCTLR_EL1_EE_MASK;
176*fc9d8ec3SMarc Zyngier 	return sctlr ? VIRTIO_ENDIAN_BE : VIRTIO_ENDIAN_LE;
177*fc9d8ec3SMarc Zyngier }
178*fc9d8ec3SMarc Zyngier 
1791e0c135aSWill Deacon void kvm_cpu__show_code(struct kvm_cpu *vcpu)
1801e0c135aSWill Deacon {
1811e0c135aSWill Deacon 	struct kvm_one_reg reg;
1821e0c135aSWill Deacon 	unsigned long data;
18330c31b66SWill Deacon 	int debug_fd = kvm_cpu__get_debug_fd();
1841e0c135aSWill Deacon 
1851e0c135aSWill Deacon 	reg.addr = (u64)&data;
1861e0c135aSWill Deacon 
18730c31b66SWill Deacon 	dprintf(debug_fd, "\n*pc:\n");
1881e0c135aSWill Deacon 	reg.id = ARM64_CORE_REG(regs.pc);
1891e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
1901e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (show_code @ PC)");
1911e0c135aSWill Deacon 
19230c31b66SWill Deacon 	kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
1931e0c135aSWill Deacon 
19430c31b66SWill Deacon 	dprintf(debug_fd, "\n*lr:\n");
1951e0c135aSWill Deacon 	reg.id = ARM64_CORE_REG(regs.regs[30]);
1961e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
1971e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (show_code @ LR)");
1981e0c135aSWill Deacon 
19930c31b66SWill Deacon 	kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
2001e0c135aSWill Deacon }
2011e0c135aSWill Deacon 
2021e0c135aSWill Deacon void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
2031e0c135aSWill Deacon {
2041e0c135aSWill Deacon 	struct kvm_one_reg reg;
2051e0c135aSWill Deacon 	unsigned long data;
2061e0c135aSWill Deacon 	int debug_fd = kvm_cpu__get_debug_fd();
2071e0c135aSWill Deacon 
2081e0c135aSWill Deacon 	reg.addr = (u64)&data;
2091e0c135aSWill Deacon 	dprintf(debug_fd, "\n Registers:\n");
2101e0c135aSWill Deacon 
2111e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.pc);
2121e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
2131e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (pc)");
2141e0c135aSWill Deacon 	dprintf(debug_fd, " PC:    0x%lx\n", data);
2151e0c135aSWill Deacon 
2161e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.pstate);
2171e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
2181e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (pstate)");
2191e0c135aSWill Deacon 	dprintf(debug_fd, " PSTATE:    0x%lx\n", data);
2201e0c135aSWill Deacon 
2211e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(sp_el1);
2221e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
2231e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (sp_el1)");
2241e0c135aSWill Deacon 	dprintf(debug_fd, " SP_EL1:    0x%lx\n", data);
2251e0c135aSWill Deacon 
2261e0c135aSWill Deacon 	reg.id		= ARM64_CORE_REG(regs.regs[30]);
2271e0c135aSWill Deacon 	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
2281e0c135aSWill Deacon 		die("KVM_GET_ONE_REG failed (lr)");
2291e0c135aSWill Deacon 	dprintf(debug_fd, " LR:    0x%lx\n", data);
2301e0c135aSWill Deacon }
231