Files
Will Deacon 91eaedaea9 kvm tools: arm: remove register accessor macros now that they are in uapi
The kernel now exposes register accessor macros in the uapi/ headers
for arm and arm64, so use those instead (and avoid the compile failure
from the duplicate definitions).

Signed-off-by: Will Deacon <will.deacon@arm.com>
2015-06-01 16:39:55 +01:00

133 lines
3.7 KiB
C

#include "kvm/kvm-cpu.h"
#include "kvm/kvm.h"
#include "kvm/virtio.h"
#include <asm/ptrace.h>
#define ARM_CORE_REG(x) (KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE | \
KVM_REG_ARM_CORE_REG(x))
unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu)
{
struct kvm_one_reg reg;
u32 mpidr;
reg.id = ARM_CP15_REG32(ARM_CPU_ID, ARM_CPU_ID_MPIDR);
reg.addr = (u64)(unsigned long)&mpidr;
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
die("KVM_GET_ONE_REG failed (get_mpidr vcpu%ld", vcpu->cpu_id);
return mpidr;
}
void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
{
struct kvm *kvm = vcpu->kvm;
struct kvm_one_reg reg;
u32 data;
/* Who said future-proofing was a good idea? */
reg.addr = (u64)(unsigned long)&data;
/* cpsr = IRQs/FIQs masked */
data = PSR_I_BIT | PSR_F_BIT | SVC_MODE;
reg.id = ARM_CORE_REG(usr_regs.ARM_cpsr);
if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
die_perror("KVM_SET_ONE_REG failed (cpsr)");
/* Secondary cores are stopped awaiting PSCI wakeup */
if (vcpu->cpu_id != 0)
return;
/* r0 = 0 */
data = 0;
reg.id = ARM_CORE_REG(usr_regs.ARM_r0);
if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
die_perror("KVM_SET_ONE_REG failed (r0)");
/* r1 = machine type (-1) */
data = -1;
reg.id = ARM_CORE_REG(usr_regs.ARM_r1);
if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
die_perror("KVM_SET_ONE_REG failed (r1)");
/* r2 = physical address of the device tree blob */
data = kvm->arch.dtb_guest_start;
reg.id = ARM_CORE_REG(usr_regs.ARM_r2);
if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
die_perror("KVM_SET_ONE_REG failed (r2)");
/* pc = start of kernel image */
data = kvm->arch.kern_guest_start;
reg.id = ARM_CORE_REG(usr_regs.ARM_pc);
if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
die_perror("KVM_SET_ONE_REG failed (pc)");
}
int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
{
struct kvm_one_reg reg;
u32 data;
reg.id = ARM_CORE_REG(usr_regs.ARM_cpsr);
reg.addr = (u64)(unsigned long)&data;
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
die("KVM_GET_ONE_REG failed (cpsr)");
return (data & PSR_E_BIT) ? VIRTIO_ENDIAN_BE : VIRTIO_ENDIAN_LE;
}
void kvm_cpu__show_code(struct kvm_cpu *vcpu)
{
struct kvm_one_reg reg;
u32 data;
int debug_fd = kvm_cpu__get_debug_fd();
reg.addr = (u64)(unsigned long)&data;
dprintf(debug_fd, "\n*pc:\n");
reg.id = ARM_CORE_REG(usr_regs.ARM_pc);
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
die("KVM_GET_ONE_REG failed (show_code @ PC)");
kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
dprintf(debug_fd, "\n*lr (svc):\n");
reg.id = ARM_CORE_REG(svc_regs[1]);
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
die("KVM_GET_ONE_REG failed (show_code @ LR_svc)");
data &= ~0x1;
kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
}
void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
{
struct kvm_one_reg reg;
u32 data;
int debug_fd = kvm_cpu__get_debug_fd();
reg.addr = (u64)(unsigned long)&data;
dprintf(debug_fd, "\n Registers:\n");
reg.id = ARM_CORE_REG(usr_regs.ARM_pc);
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
die("KVM_GET_ONE_REG failed (pc)");
dprintf(debug_fd, " PC: 0x%x\n", data);
reg.id = ARM_CORE_REG(usr_regs.ARM_cpsr);
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
die("KVM_GET_ONE_REG failed (cpsr)");
dprintf(debug_fd, " CPSR: 0x%x\n", data);
reg.id = ARM_CORE_REG(svc_regs[0]);
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
die("KVM_GET_ONE_REG failed (SP_svc)");
dprintf(debug_fd, " SP_svc: 0x%x\n", data);
reg.id = ARM_CORE_REG(svc_regs[1]);
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
die("KVM_GET_ONE_REG failed (LR_svc)");
dprintf(debug_fd, " LR_svc: 0x%x\n", data);
}