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_ioport_region(phys_addr)) { 107 int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN; 108 u16 port = phys_addr & USHRT_MAX; 109 return kvm__emulate_io(kvm, port, data, direction, len, 1); 110 } else if (arm_addr_in_pci_region(phys_addr)) { 111 return kvm__emulate_mmio(kvm, phys_addr, data, len, is_write); 112 } 113 114 return false; 115 } 116 117 void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) 118 { 119 } 120