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