xref: /kvmtool/arm/kvm-cpu.c (revision 9b47146bc9a1ff1a08d6e2e2f9cb517e075dd662)
1 #include "kvm/kvm.h"
2 #include "kvm/kvm-cpu.h"
3 
4 static int debug_fd;
5 
6 void kvm_cpu__set_debug_fd(int fd)
7 {
8 	debug_fd = fd;
9 }
10 
11 int kvm_cpu__get_debug_fd(void)
12 {
13 	return debug_fd;
14 }
15 
16 static struct kvm_arm_target *kvm_arm_targets[KVM_ARM_NUM_TARGETS];
17 int kvm_cpu__register_kvm_arm_target(struct kvm_arm_target *target)
18 {
19 	unsigned int i = 0;
20 
21 	for (i = 0; i < ARRAY_SIZE(kvm_arm_targets); ++i) {
22 		if (!kvm_arm_targets[i]) {
23 			kvm_arm_targets[i] = target;
24 			return 0;
25 		}
26 	}
27 
28 	return -ENOSPC;
29 }
30 
31 struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
32 {
33 	struct kvm_arm_target *target;
34 	struct kvm_cpu *vcpu;
35 	int coalesced_offset, mmap_size, err = -1;
36 	unsigned int i;
37 	struct kvm_vcpu_init vcpu_init = {
38 		.features = ARM_VCPU_FEATURE_FLAGS(kvm, cpu_id)
39 	};
40 
41 	vcpu = calloc(1, sizeof(struct kvm_cpu));
42 	if (!vcpu)
43 		return NULL;
44 
45 	vcpu->vcpu_fd = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, cpu_id);
46 	if (vcpu->vcpu_fd < 0)
47 		die_perror("KVM_CREATE_VCPU ioctl");
48 
49 	mmap_size = ioctl(kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
50 	if (mmap_size < 0)
51 		die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl");
52 
53 	vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED,
54 			     vcpu->vcpu_fd, 0);
55 	if (vcpu->kvm_run == MAP_FAILED)
56 		die("unable to mmap vcpu fd");
57 
58 	/* Find an appropriate target CPU type. */
59 	for (i = 0; i < ARRAY_SIZE(kvm_arm_targets); ++i) {
60 		if (!kvm_arm_targets[i])
61 			continue;
62 		target = kvm_arm_targets[i];
63 		vcpu_init.target = target->id;
64 		err = ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_INIT, &vcpu_init);
65 		if (!err)
66 			break;
67 	}
68 
69 	if (err || target->init(vcpu))
70 		die("Unable to initialise ARM vcpu");
71 
72 	coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION,
73 				 KVM_CAP_COALESCED_MMIO);
74 	if (coalesced_offset)
75 		vcpu->ring = (void *)vcpu->kvm_run +
76 			     (coalesced_offset * PAGE_SIZE);
77 
78 	/* Populate the vcpu structure. */
79 	vcpu->kvm		= kvm;
80 	vcpu->cpu_id		= cpu_id;
81 	vcpu->cpu_type		= target->id;
82 	vcpu->cpu_compatible	= target->compatible;
83 	vcpu->is_running	= true;
84 	return vcpu;
85 }
86 
87 void kvm_cpu__arch_nmi(struct kvm_cpu *cpu)
88 {
89 }
90 
91 void kvm_cpu__delete(struct kvm_cpu *vcpu)
92 {
93 	free(vcpu);
94 }
95 
96 bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
97 {
98 	return false;
99 }
100 
101 bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len,
102 			   u8 is_write)
103 {
104 	if (arm_addr_in_virtio_mmio_region(phys_addr))
105 		return kvm__emulate_mmio(kvm, phys_addr, data, len, is_write);
106 	else if (arm_addr_in_pci_mmio_region(phys_addr))
107 		die("PCI emulation not supported on ARM!");
108 
109 	return false;
110 }
111 
112 void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
113 {
114 }
115