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_generic_target; 17 static struct kvm_arm_target *kvm_arm_targets[KVM_ARM_NUM_TARGETS]; 18 19 void kvm_cpu__set_kvm_arm_generic_target(struct kvm_arm_target *target) 20 { 21 kvm_arm_generic_target = target; 22 } 23 24 int kvm_cpu__register_kvm_arm_target(struct kvm_arm_target *target) 25 { 26 unsigned int i = 0; 27 28 for (i = 0; i < ARRAY_SIZE(kvm_arm_targets); ++i) { 29 if (!kvm_arm_targets[i]) { 30 kvm_arm_targets[i] = target; 31 return 0; 32 } 33 } 34 35 return -ENOSPC; 36 } 37 38 struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) 39 { 40 struct kvm_arm_target *target; 41 struct kvm_cpu *vcpu; 42 int coalesced_offset, mmap_size, err = -1; 43 unsigned int i; 44 struct kvm_vcpu_init preferred_init; 45 struct kvm_vcpu_init vcpu_init = { 46 .features = ARM_VCPU_FEATURE_FLAGS(kvm, cpu_id) 47 }; 48 49 if (kvm->cfg.arch.aarch32_guest && 50 !kvm__supports_extension(kvm, KVM_CAP_ARM_EL1_32BIT)) 51 die("32bit guests are not supported\n"); 52 53 if (kvm->cfg.arch.has_pmuv3 && 54 !kvm__supports_extension(kvm, KVM_CAP_ARM_PMU_V3)) 55 die("PMUv3 is not supported"); 56 57 vcpu = calloc(1, sizeof(struct kvm_cpu)); 58 if (!vcpu) 59 return NULL; 60 61 vcpu->vcpu_fd = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, cpu_id); 62 if (vcpu->vcpu_fd < 0) 63 die_perror("KVM_CREATE_VCPU ioctl"); 64 65 mmap_size = ioctl(kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); 66 if (mmap_size < 0) 67 die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl"); 68 69 vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, 70 vcpu->vcpu_fd, 0); 71 if (vcpu->kvm_run == MAP_FAILED) 72 die("unable to mmap vcpu fd"); 73 74 /* Set KVM_ARM_VCPU_PSCI_0_2 if available */ 75 if (kvm__supports_extension(kvm, KVM_CAP_ARM_PSCI_0_2)) { 76 vcpu_init.features[0] |= (1UL << KVM_ARM_VCPU_PSCI_0_2); 77 } 78 79 kvm_cpu__select_features(kvm, &vcpu_init); 80 81 /* 82 * If the preferred target ioctl is successful then 83 * use preferred target else try each and every target type 84 */ 85 err = ioctl(kvm->vm_fd, KVM_ARM_PREFERRED_TARGET, &preferred_init); 86 if (!err) { 87 /* Match preferred target CPU type. */ 88 target = NULL; 89 for (i = 0; i < ARRAY_SIZE(kvm_arm_targets); ++i) { 90 if (!kvm_arm_targets[i]) 91 continue; 92 if (kvm_arm_targets[i]->id == preferred_init.target) { 93 target = kvm_arm_targets[i]; 94 break; 95 } 96 } 97 if (!target) { 98 target = kvm_arm_generic_target; 99 vcpu_init.target = preferred_init.target; 100 } else { 101 vcpu_init.target = target->id; 102 } 103 err = ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_INIT, &vcpu_init); 104 } else { 105 /* Find an appropriate target CPU type. */ 106 for (i = 0; i < ARRAY_SIZE(kvm_arm_targets); ++i) { 107 if (!kvm_arm_targets[i]) 108 continue; 109 target = kvm_arm_targets[i]; 110 vcpu_init.target = target->id; 111 err = ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_INIT, &vcpu_init); 112 if (!err) 113 break; 114 } 115 if (err) 116 die("Unable to find matching target"); 117 } 118 119 if (err || target->init(vcpu)) 120 die("Unable to initialise vcpu"); 121 122 coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, 123 KVM_CAP_COALESCED_MMIO); 124 if (coalesced_offset) 125 vcpu->ring = (void *)vcpu->kvm_run + 126 (coalesced_offset * PAGE_SIZE); 127 128 /* Populate the vcpu structure. */ 129 vcpu->kvm = kvm; 130 vcpu->cpu_id = cpu_id; 131 vcpu->cpu_type = vcpu_init.target; 132 vcpu->cpu_compatible = target->compatible; 133 vcpu->is_running = true; 134 135 if (kvm_cpu__configure_features(vcpu)) 136 die("Unable to configure requested vcpu features"); 137 138 return vcpu; 139 } 140 141 void kvm_cpu__arch_nmi(struct kvm_cpu *cpu) 142 { 143 } 144 145 void kvm_cpu__delete(struct kvm_cpu *vcpu) 146 { 147 free(vcpu); 148 } 149 150 bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) 151 { 152 return false; 153 } 154 155 void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) 156 { 157 } 158