1*7281a8dbSDavid Daney #include "kvm/kvm.h" 2*7281a8dbSDavid Daney #include "kvm/ioport.h" 3*7281a8dbSDavid Daney #include "kvm/virtio-console.h" 4*7281a8dbSDavid Daney 5*7281a8dbSDavid Daney #include <linux/kvm.h> 6*7281a8dbSDavid Daney 7*7281a8dbSDavid Daney #include <ctype.h> 8*7281a8dbSDavid Daney #include <unistd.h> 9*7281a8dbSDavid Daney 10*7281a8dbSDavid Daney struct kvm_ext kvm_req_ext[] = { 11*7281a8dbSDavid Daney { 0, 0 } 12*7281a8dbSDavid Daney }; 13*7281a8dbSDavid Daney 14*7281a8dbSDavid Daney void kvm__arch_read_term(struct kvm *kvm) 15*7281a8dbSDavid Daney { 16*7281a8dbSDavid Daney virtio_console__inject_interrupt(kvm); 17*7281a8dbSDavid Daney } 18*7281a8dbSDavid Daney 19*7281a8dbSDavid Daney void kvm__init_ram(struct kvm *kvm) 20*7281a8dbSDavid Daney { 21*7281a8dbSDavid Daney u64 phys_start, phys_size; 22*7281a8dbSDavid Daney void *host_mem; 23*7281a8dbSDavid Daney 24*7281a8dbSDavid Daney phys_start = 0; 25*7281a8dbSDavid Daney phys_size = kvm->ram_size; 26*7281a8dbSDavid Daney host_mem = kvm->ram_start; 27*7281a8dbSDavid Daney 28*7281a8dbSDavid Daney kvm__register_mem(kvm, phys_start, phys_size, host_mem); 29*7281a8dbSDavid Daney } 30*7281a8dbSDavid Daney 31*7281a8dbSDavid Daney void kvm__arch_delete_ram(struct kvm *kvm) 32*7281a8dbSDavid Daney { 33*7281a8dbSDavid Daney munmap(kvm->ram_start, kvm->ram_size); 34*7281a8dbSDavid Daney } 35*7281a8dbSDavid Daney 36*7281a8dbSDavid Daney void kvm__arch_set_cmdline(char *cmdline, bool video) 37*7281a8dbSDavid Daney { 38*7281a8dbSDavid Daney 39*7281a8dbSDavid Daney } 40*7281a8dbSDavid Daney 41*7281a8dbSDavid Daney /* Architecture-specific KVM init */ 42*7281a8dbSDavid Daney void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size) 43*7281a8dbSDavid Daney { 44*7281a8dbSDavid Daney int ret; 45*7281a8dbSDavid Daney 46*7281a8dbSDavid Daney kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size); 47*7281a8dbSDavid Daney kvm->ram_size = ram_size; 48*7281a8dbSDavid Daney 49*7281a8dbSDavid Daney if (kvm->ram_start == MAP_FAILED) 50*7281a8dbSDavid Daney die("out of memory"); 51*7281a8dbSDavid Daney 52*7281a8dbSDavid Daney madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE); 53*7281a8dbSDavid Daney 54*7281a8dbSDavid Daney ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP); 55*7281a8dbSDavid Daney if (ret < 0) 56*7281a8dbSDavid Daney die_perror("KVM_CREATE_IRQCHIP ioctl"); 57*7281a8dbSDavid Daney } 58*7281a8dbSDavid Daney 59*7281a8dbSDavid Daney void kvm__irq_line(struct kvm *kvm, int irq, int level) 60*7281a8dbSDavid Daney { 61*7281a8dbSDavid Daney struct kvm_irq_level irq_level; 62*7281a8dbSDavid Daney int ret; 63*7281a8dbSDavid Daney 64*7281a8dbSDavid Daney irq_level.irq = irq; 65*7281a8dbSDavid Daney irq_level.level = level ? 1 : 0; 66*7281a8dbSDavid Daney 67*7281a8dbSDavid Daney ret = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level); 68*7281a8dbSDavid Daney if (ret < 0) 69*7281a8dbSDavid Daney die_perror("KVM_IRQ_LINE ioctl"); 70*7281a8dbSDavid Daney } 71*7281a8dbSDavid Daney 72*7281a8dbSDavid Daney void kvm__irq_trigger(struct kvm *kvm, int irq) 73*7281a8dbSDavid Daney { 74*7281a8dbSDavid Daney struct kvm_irq_level irq_level; 75*7281a8dbSDavid Daney int ret; 76*7281a8dbSDavid Daney 77*7281a8dbSDavid Daney irq_level.irq = irq; 78*7281a8dbSDavid Daney irq_level.level = 1; 79*7281a8dbSDavid Daney 80*7281a8dbSDavid Daney ret = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level); 81*7281a8dbSDavid Daney if (ret < 0) 82*7281a8dbSDavid Daney die_perror("KVM_IRQ_LINE ioctl"); 83*7281a8dbSDavid Daney } 84*7281a8dbSDavid Daney 85*7281a8dbSDavid Daney void ioport__setup_arch(struct kvm *kvm) 86*7281a8dbSDavid Daney { 87*7281a8dbSDavid Daney } 88*7281a8dbSDavid Daney 89*7281a8dbSDavid Daney bool kvm__arch_cpu_supports_vm(void) 90*7281a8dbSDavid Daney { 91*7281a8dbSDavid Daney return true; 92*7281a8dbSDavid Daney } 93*7281a8dbSDavid Daney bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename) 94*7281a8dbSDavid Daney { 95*7281a8dbSDavid Daney return false; 96*7281a8dbSDavid Daney } 97*7281a8dbSDavid Daney int kvm__arch_setup_firmware(struct kvm *kvm) 98*7281a8dbSDavid Daney { 99*7281a8dbSDavid Daney return 0; 100*7281a8dbSDavid Daney } 101*7281a8dbSDavid Daney 102*7281a8dbSDavid Daney /* Load at the 1M point. */ 103*7281a8dbSDavid Daney #define KERNEL_LOAD_ADDR 0x1000000 104*7281a8dbSDavid Daney int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline) 105*7281a8dbSDavid Daney { 106*7281a8dbSDavid Daney void *p; 107*7281a8dbSDavid Daney void *k_start; 108*7281a8dbSDavid Daney int nr; 109*7281a8dbSDavid Daney 110*7281a8dbSDavid Daney if (lseek(fd_kernel, 0, SEEK_SET) < 0) 111*7281a8dbSDavid Daney die_perror("lseek"); 112*7281a8dbSDavid Daney 113*7281a8dbSDavid Daney p = k_start = guest_flat_to_host(kvm, KERNEL_LOAD_ADDR); 114*7281a8dbSDavid Daney 115*7281a8dbSDavid Daney while ((nr = read(fd_kernel, p, 65536)) > 0) 116*7281a8dbSDavid Daney p += nr; 117*7281a8dbSDavid Daney 118*7281a8dbSDavid Daney kvm->arch.is64bit = true; 119*7281a8dbSDavid Daney kvm->arch.entry_point = 0xffffffff81000000ull; 120*7281a8dbSDavid Daney 121*7281a8dbSDavid Daney pr_info("Loaded kernel to 0x%x (%ld bytes)", KERNEL_LOAD_ADDR, (long int)(p - k_start)); 122*7281a8dbSDavid Daney 123*7281a8dbSDavid Daney return true; 124*7281a8dbSDavid Daney } 125*7281a8dbSDavid Daney 126*7281a8dbSDavid Daney void ioport__map_irq(u8 *irq) 127*7281a8dbSDavid Daney { 128*7281a8dbSDavid Daney } 129