16f6f384cSAlexandru Elisei #include "kvm/8250-serial.h"
27281a8dbSDavid Daney #include "kvm/kvm.h"
37281a8dbSDavid Daney #include "kvm/ioport.h"
47281a8dbSDavid Daney #include "kvm/virtio-console.h"
57281a8dbSDavid Daney
67281a8dbSDavid Daney #include <linux/kvm.h>
77281a8dbSDavid Daney
87281a8dbSDavid Daney #include <ctype.h>
97281a8dbSDavid Daney #include <unistd.h>
101ade2d7dSDavid Daney #include <elf.h>
117281a8dbSDavid Daney
127281a8dbSDavid Daney struct kvm_ext kvm_req_ext[] = {
137281a8dbSDavid Daney { 0, 0 }
147281a8dbSDavid Daney };
157281a8dbSDavid Daney
kvm__arch_default_ram_address(void)16*3f7e48f6SAlexandru Elisei u64 kvm__arch_default_ram_address(void)
17*3f7e48f6SAlexandru Elisei {
18*3f7e48f6SAlexandru Elisei return 0;
19*3f7e48f6SAlexandru Elisei }
20*3f7e48f6SAlexandru Elisei
kvm__arch_validate_cfg(struct kvm * kvm)21abe3f28aSAlexandru Elisei void kvm__arch_validate_cfg(struct kvm *kvm)
22abe3f28aSAlexandru Elisei {
23abe3f28aSAlexandru Elisei }
24abe3f28aSAlexandru Elisei
kvm__arch_read_term(struct kvm * kvm)257281a8dbSDavid Daney void kvm__arch_read_term(struct kvm *kvm)
267281a8dbSDavid Daney {
277281a8dbSDavid Daney virtio_console__inject_interrupt(kvm);
287281a8dbSDavid Daney }
297281a8dbSDavid Daney
kvm__init_ram(struct kvm * kvm)307281a8dbSDavid Daney void kvm__init_ram(struct kvm *kvm)
317281a8dbSDavid Daney {
327281a8dbSDavid Daney u64 phys_start, phys_size;
337281a8dbSDavid Daney void *host_mem;
347281a8dbSDavid Daney
3557896feeSAndreas Herrmann if (kvm->ram_size <= KVM_MMIO_START) {
3657896feeSAndreas Herrmann /* one region for all memory */
377281a8dbSDavid Daney phys_start = 0;
387281a8dbSDavid Daney phys_size = kvm->ram_size;
397281a8dbSDavid Daney host_mem = kvm->ram_start;
407281a8dbSDavid Daney
418f46c736SJean-Philippe Brucker kvm__register_ram(kvm, phys_start, phys_size, host_mem);
4257896feeSAndreas Herrmann } else {
4357896feeSAndreas Herrmann /* one region for memory that fits below MMIO range */
4457896feeSAndreas Herrmann phys_start = 0;
4557896feeSAndreas Herrmann phys_size = KVM_MMIO_START;
4657896feeSAndreas Herrmann host_mem = kvm->ram_start;
4757896feeSAndreas Herrmann
488f46c736SJean-Philippe Brucker kvm__register_ram(kvm, phys_start, phys_size, host_mem);
4957896feeSAndreas Herrmann
5057896feeSAndreas Herrmann /* one region for rest of memory */
5157896feeSAndreas Herrmann phys_start = KVM_MMIO_START + KVM_MMIO_SIZE;
5257896feeSAndreas Herrmann phys_size = kvm->ram_size - KVM_MMIO_START;
5357896feeSAndreas Herrmann host_mem = kvm->ram_start + KVM_MMIO_START;
5457896feeSAndreas Herrmann
558f46c736SJean-Philippe Brucker kvm__register_ram(kvm, phys_start, phys_size, host_mem);
5657896feeSAndreas Herrmann }
577281a8dbSDavid Daney }
587281a8dbSDavid Daney
kvm__arch_delete_ram(struct kvm * kvm)597281a8dbSDavid Daney void kvm__arch_delete_ram(struct kvm *kvm)
607281a8dbSDavid Daney {
617281a8dbSDavid Daney munmap(kvm->ram_start, kvm->ram_size);
627281a8dbSDavid Daney }
637281a8dbSDavid Daney
kvm__arch_set_cmdline(char * cmdline,bool video)647281a8dbSDavid Daney void kvm__arch_set_cmdline(char *cmdline, bool video)
657281a8dbSDavid Daney {
667281a8dbSDavid Daney
677281a8dbSDavid Daney }
687281a8dbSDavid Daney
697281a8dbSDavid Daney /* Architecture-specific KVM init */
kvm__arch_init(struct kvm * kvm)705e9c654eSJulien Grall void kvm__arch_init(struct kvm *kvm)
717281a8dbSDavid Daney {
727281a8dbSDavid Daney int ret;
737281a8dbSDavid Daney
745e9c654eSJulien Grall kvm->ram_size = kvm->cfg.ram_size;
755e9c654eSJulien Grall kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, kvm->cfg.hugetlbfs_path,
765e9c654eSJulien Grall kvm->ram_size);
777281a8dbSDavid Daney
787281a8dbSDavid Daney if (kvm->ram_start == MAP_FAILED)
797281a8dbSDavid Daney die("out of memory");
807281a8dbSDavid Daney
817281a8dbSDavid Daney madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
827281a8dbSDavid Daney
837281a8dbSDavid Daney ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
847281a8dbSDavid Daney if (ret < 0)
857281a8dbSDavid Daney die_perror("KVM_CREATE_IRQCHIP ioctl");
867281a8dbSDavid Daney }
877281a8dbSDavid Daney
kvm__irq_line(struct kvm * kvm,int irq,int level)887281a8dbSDavid Daney void kvm__irq_line(struct kvm *kvm, int irq, int level)
897281a8dbSDavid Daney {
907281a8dbSDavid Daney struct kvm_irq_level irq_level;
917281a8dbSDavid Daney int ret;
927281a8dbSDavid Daney
937281a8dbSDavid Daney irq_level.irq = irq;
947281a8dbSDavid Daney irq_level.level = level ? 1 : 0;
957281a8dbSDavid Daney
967281a8dbSDavid Daney ret = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level);
977281a8dbSDavid Daney if (ret < 0)
987281a8dbSDavid Daney die_perror("KVM_IRQ_LINE ioctl");
997281a8dbSDavid Daney }
1007281a8dbSDavid Daney
kvm__irq_trigger(struct kvm * kvm,int irq)1017281a8dbSDavid Daney void kvm__irq_trigger(struct kvm *kvm, int irq)
1027281a8dbSDavid Daney {
1037281a8dbSDavid Daney struct kvm_irq_level irq_level;
1047281a8dbSDavid Daney int ret;
1057281a8dbSDavid Daney
1067281a8dbSDavid Daney irq_level.irq = irq;
1077281a8dbSDavid Daney irq_level.level = 1;
1087281a8dbSDavid Daney
1097281a8dbSDavid Daney ret = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level);
1107281a8dbSDavid Daney if (ret < 0)
1117281a8dbSDavid Daney die_perror("KVM_IRQ_LINE ioctl");
1127281a8dbSDavid Daney }
1137281a8dbSDavid Daney
kvm__arch_cpu_supports_vm(void)1147281a8dbSDavid Daney bool kvm__arch_cpu_supports_vm(void)
1157281a8dbSDavid Daney {
1167281a8dbSDavid Daney return true;
1177281a8dbSDavid Daney }
kvm__load_firmware(struct kvm * kvm,const char * firmware_filename)1187281a8dbSDavid Daney bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
1197281a8dbSDavid Daney {
1207281a8dbSDavid Daney return false;
1217281a8dbSDavid Daney }
kvm__arch_setup_firmware(struct kvm * kvm)1227281a8dbSDavid Daney int kvm__arch_setup_firmware(struct kvm *kvm)
1237281a8dbSDavid Daney {
1247281a8dbSDavid Daney return 0;
1257281a8dbSDavid Daney }
1267281a8dbSDavid Daney
kvm__mips_install_cmdline(struct kvm * kvm)1271ade2d7dSDavid Daney static void kvm__mips_install_cmdline(struct kvm *kvm)
1281ade2d7dSDavid Daney {
1291ade2d7dSDavid Daney char *p = kvm->ram_start;
1301ade2d7dSDavid Daney u64 cmdline_offset = 0x2000;
1311ade2d7dSDavid Daney u64 argv_start = 0x3000;
1321ade2d7dSDavid Daney u64 argv_offset = argv_start;
1331ade2d7dSDavid Daney u64 argc = 0;
1341ade2d7dSDavid Daney
13557896feeSAndreas Herrmann
13657896feeSAndreas Herrmann if ((u64) kvm->ram_size <= KVM_MMIO_START)
1371ade2d7dSDavid Daney sprintf(p + cmdline_offset, "mem=0x%llx@0 ",
1381ade2d7dSDavid Daney (unsigned long long)kvm->ram_size);
13957896feeSAndreas Herrmann else
14057896feeSAndreas Herrmann sprintf(p + cmdline_offset, "mem=0x%llx@0 mem=0x%llx@0x%llx ",
14157896feeSAndreas Herrmann (unsigned long long)KVM_MMIO_START,
14257896feeSAndreas Herrmann (unsigned long long)kvm->ram_size - KVM_MMIO_START,
14357896feeSAndreas Herrmann (unsigned long long)(KVM_MMIO_START + KVM_MMIO_SIZE));
1441ade2d7dSDavid Daney
1455613ae26SAlexandru Elisei if (kvm->cfg.real_cmdline)
1461ade2d7dSDavid Daney strcat(p + cmdline_offset, kvm->cfg.real_cmdline); /* maximum size is 2K */
1471ade2d7dSDavid Daney
1481ade2d7dSDavid Daney while (p[cmdline_offset]) {
1491ade2d7dSDavid Daney if (!isspace(p[cmdline_offset])) {
1501ade2d7dSDavid Daney if (kvm->arch.is64bit) {
1511ade2d7dSDavid Daney *(u64 *)(p + argv_offset) = 0xffffffff80000000ull + cmdline_offset;
1521ade2d7dSDavid Daney argv_offset += sizeof(u64);
1531ade2d7dSDavid Daney } else {
1541ade2d7dSDavid Daney *(u32 *)(p + argv_offset) = 0x80000000u + cmdline_offset;
1551ade2d7dSDavid Daney argv_offset += sizeof(u32);
1561ade2d7dSDavid Daney }
1571ade2d7dSDavid Daney argc++;
1581ade2d7dSDavid Daney while(p[cmdline_offset] && !isspace(p[cmdline_offset]))
1591ade2d7dSDavid Daney cmdline_offset++;
1601ade2d7dSDavid Daney continue;
1611ade2d7dSDavid Daney }
1621ade2d7dSDavid Daney /* Must be a space character skip over these*/
1631ade2d7dSDavid Daney while(p[cmdline_offset] && isspace(p[cmdline_offset])) {
1641ade2d7dSDavid Daney p[cmdline_offset] = 0;
1651ade2d7dSDavid Daney cmdline_offset++;
1661ade2d7dSDavid Daney }
1671ade2d7dSDavid Daney }
1681ade2d7dSDavid Daney kvm->arch.argc = argc;
1691ade2d7dSDavid Daney kvm->arch.argv = 0xffffffff80000000ull + argv_start;
1701ade2d7dSDavid Daney }
1711ade2d7dSDavid Daney
1727281a8dbSDavid Daney /* Load at the 1M point. */
1737281a8dbSDavid Daney #define KERNEL_LOAD_ADDR 0x1000000
174004f7684SAndre Przywara
load_flat_binary(struct kvm * kvm,int fd_kernel)175004f7684SAndre Przywara static bool load_flat_binary(struct kvm *kvm, int fd_kernel)
1767281a8dbSDavid Daney {
1777281a8dbSDavid Daney void *p;
1787281a8dbSDavid Daney void *k_start;
17912225973SAndre Przywara ssize_t kernel_size;
1807281a8dbSDavid Daney
1817281a8dbSDavid Daney if (lseek(fd_kernel, 0, SEEK_SET) < 0)
1827281a8dbSDavid Daney die_perror("lseek");
1837281a8dbSDavid Daney
1847281a8dbSDavid Daney p = k_start = guest_flat_to_host(kvm, KERNEL_LOAD_ADDR);
1857281a8dbSDavid Daney
18612225973SAndre Przywara kernel_size = read_file(fd_kernel, p,
18712225973SAndre Przywara kvm->cfg.ram_size - KERNEL_LOAD_ADDR);
18812225973SAndre Przywara if (kernel_size == -1) {
18912225973SAndre Przywara if (errno == ENOMEM)
19012225973SAndre Przywara die("kernel too big for guest memory");
19112225973SAndre Przywara else
19212225973SAndre Przywara die_perror("kernel read");
19312225973SAndre Przywara }
1947281a8dbSDavid Daney
1957281a8dbSDavid Daney kvm->arch.is64bit = true;
1967281a8dbSDavid Daney kvm->arch.entry_point = 0xffffffff81000000ull;
1977281a8dbSDavid Daney
19812225973SAndre Przywara pr_info("Loaded kernel to 0x%x (%zd bytes)", KERNEL_LOAD_ADDR,
19912225973SAndre Przywara kernel_size);
2007281a8dbSDavid Daney
2017281a8dbSDavid Daney return true;
2027281a8dbSDavid Daney }
2037281a8dbSDavid Daney
2041ade2d7dSDavid Daney struct kvm__arch_elf_info {
2051ade2d7dSDavid Daney u64 load_addr;
2061ade2d7dSDavid Daney u64 entry_point;
2071ade2d7dSDavid Daney size_t len;
2081ade2d7dSDavid Daney size_t offset;
2091ade2d7dSDavid Daney };
2101ade2d7dSDavid Daney
kvm__arch_get_elf_64_info(Elf64_Ehdr * ehdr,int fd_kernel,struct kvm__arch_elf_info * ei)2111ade2d7dSDavid Daney static bool kvm__arch_get_elf_64_info(Elf64_Ehdr *ehdr, int fd_kernel,
2121ade2d7dSDavid Daney struct kvm__arch_elf_info *ei)
2131ade2d7dSDavid Daney {
2141ade2d7dSDavid Daney int i;
2151ade2d7dSDavid Daney Elf64_Phdr phdr;
2161ade2d7dSDavid Daney
2171ade2d7dSDavid Daney if (ehdr->e_phentsize != sizeof(phdr)) {
2181ade2d7dSDavid Daney pr_info("Incompatible ELF PHENTSIZE %d", ehdr->e_phentsize);
2191ade2d7dSDavid Daney return false;
2201ade2d7dSDavid Daney }
2211ade2d7dSDavid Daney
2221ade2d7dSDavid Daney ei->entry_point = ehdr->e_entry;
2231ade2d7dSDavid Daney
2241ade2d7dSDavid Daney if (lseek(fd_kernel, ehdr->e_phoff, SEEK_SET) < 0)
2251ade2d7dSDavid Daney die_perror("lseek");
2261ade2d7dSDavid Daney
2271ade2d7dSDavid Daney phdr.p_type = PT_NULL;
2281ade2d7dSDavid Daney for (i = 0; i < ehdr->e_phnum; i++) {
22912225973SAndre Przywara if (read_in_full(fd_kernel, &phdr, sizeof(phdr)) != sizeof(phdr)) {
2301ade2d7dSDavid Daney pr_info("Couldn't read %d bytes for ELF PHDR.", (int)sizeof(phdr));
2311ade2d7dSDavid Daney return false;
2321ade2d7dSDavid Daney }
2331ade2d7dSDavid Daney if (phdr.p_type == PT_LOAD)
2341ade2d7dSDavid Daney break;
2351ade2d7dSDavid Daney }
2361ade2d7dSDavid Daney if (phdr.p_type != PT_LOAD) {
2371ade2d7dSDavid Daney pr_info("No PT_LOAD Program Header found.");
2381ade2d7dSDavid Daney return false;
2391ade2d7dSDavid Daney }
2401ade2d7dSDavid Daney
2411ade2d7dSDavid Daney ei->load_addr = phdr.p_paddr;
2421ade2d7dSDavid Daney
2431ade2d7dSDavid Daney if ((ei->load_addr & 0xffffffffc0000000ull) == 0xffffffff80000000ull)
2441ade2d7dSDavid Daney ei->load_addr &= 0x1ffffffful; /* Convert KSEG{0,1} to physical. */
2451ade2d7dSDavid Daney if ((ei->load_addr & 0xc000000000000000ull) == 0x8000000000000000ull)
2461ade2d7dSDavid Daney ei->load_addr &= 0x07ffffffffffffffull; /* Convert XKPHYS to pysical */
2471ade2d7dSDavid Daney
2481ade2d7dSDavid Daney
2491ade2d7dSDavid Daney ei->len = phdr.p_filesz;
2501ade2d7dSDavid Daney ei->offset = phdr.p_offset;
2511ade2d7dSDavid Daney
2521ade2d7dSDavid Daney return true;
2531ade2d7dSDavid Daney }
2541ade2d7dSDavid Daney
kvm__arch_get_elf_32_info(Elf32_Ehdr * ehdr,int fd_kernel,struct kvm__arch_elf_info * ei)2551ade2d7dSDavid Daney static bool kvm__arch_get_elf_32_info(Elf32_Ehdr *ehdr, int fd_kernel,
2561ade2d7dSDavid Daney struct kvm__arch_elf_info *ei)
2571ade2d7dSDavid Daney {
2581ade2d7dSDavid Daney int i;
2591ade2d7dSDavid Daney Elf32_Phdr phdr;
2601ade2d7dSDavid Daney
2611ade2d7dSDavid Daney if (ehdr->e_phentsize != sizeof(phdr)) {
2621ade2d7dSDavid Daney pr_info("Incompatible ELF PHENTSIZE %d", ehdr->e_phentsize);
2631ade2d7dSDavid Daney return false;
2641ade2d7dSDavid Daney }
2651ade2d7dSDavid Daney
2661ade2d7dSDavid Daney ei->entry_point = (s64)((s32)ehdr->e_entry);
2671ade2d7dSDavid Daney
2681ade2d7dSDavid Daney if (lseek(fd_kernel, ehdr->e_phoff, SEEK_SET) < 0)
2691ade2d7dSDavid Daney die_perror("lseek");
2701ade2d7dSDavid Daney
2711ade2d7dSDavid Daney phdr.p_type = PT_NULL;
2721ade2d7dSDavid Daney for (i = 0; i < ehdr->e_phnum; i++) {
27312225973SAndre Przywara if (read_in_full(fd_kernel, &phdr, sizeof(phdr)) != sizeof(phdr)) {
2741ade2d7dSDavid Daney pr_info("Couldn't read %d bytes for ELF PHDR.", (int)sizeof(phdr));
2751ade2d7dSDavid Daney return false;
2761ade2d7dSDavid Daney }
2771ade2d7dSDavid Daney if (phdr.p_type == PT_LOAD)
2781ade2d7dSDavid Daney break;
2791ade2d7dSDavid Daney }
2801ade2d7dSDavid Daney if (phdr.p_type != PT_LOAD) {
2811ade2d7dSDavid Daney pr_info("No PT_LOAD Program Header found.");
2821ade2d7dSDavid Daney return false;
2831ade2d7dSDavid Daney }
2841ade2d7dSDavid Daney
2851ade2d7dSDavid Daney ei->load_addr = (s64)((s32)phdr.p_paddr);
2861ade2d7dSDavid Daney
2871ade2d7dSDavid Daney if ((ei->load_addr & 0xffffffffc0000000ull) == 0xffffffff80000000ull)
2881ade2d7dSDavid Daney ei->load_addr &= 0x1fffffffull; /* Convert KSEG{0,1} to physical. */
2891ade2d7dSDavid Daney
2901ade2d7dSDavid Daney ei->len = phdr.p_filesz;
2911ade2d7dSDavid Daney ei->offset = phdr.p_offset;
2921ade2d7dSDavid Daney
2931ade2d7dSDavid Daney return true;
2941ade2d7dSDavid Daney }
2951ade2d7dSDavid Daney
load_elf_binary(struct kvm * kvm,int fd_kernel)296004f7684SAndre Przywara static bool load_elf_binary(struct kvm *kvm, int fd_kernel)
2971ade2d7dSDavid Daney {
2981ade2d7dSDavid Daney union {
2991ade2d7dSDavid Daney Elf64_Ehdr ehdr;
3001ade2d7dSDavid Daney Elf32_Ehdr ehdr32;
3011ade2d7dSDavid Daney } eh;
3021ade2d7dSDavid Daney
3031ade2d7dSDavid Daney size_t nr;
3041ade2d7dSDavid Daney char *p;
3051ade2d7dSDavid Daney struct kvm__arch_elf_info ei;
3061ade2d7dSDavid Daney
3071ade2d7dSDavid Daney nr = read(fd_kernel, &eh, sizeof(eh));
3081ade2d7dSDavid Daney if (nr != sizeof(eh)) {
3091ade2d7dSDavid Daney pr_info("Couldn't read %d bytes for ELF header.", (int)sizeof(eh));
3101ade2d7dSDavid Daney return false;
3111ade2d7dSDavid Daney }
3121ade2d7dSDavid Daney
3131ade2d7dSDavid Daney if (eh.ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
3141ade2d7dSDavid Daney eh.ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
3151ade2d7dSDavid Daney eh.ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
3161ade2d7dSDavid Daney eh.ehdr.e_ident[EI_MAG3] != ELFMAG3 ||
3171ade2d7dSDavid Daney (eh.ehdr.e_ident[EI_CLASS] != ELFCLASS64 && eh.ehdr.e_ident[EI_CLASS] != ELFCLASS32) ||
3181ade2d7dSDavid Daney eh.ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
3191ade2d7dSDavid Daney pr_info("Incompatible ELF header.");
3201ade2d7dSDavid Daney return false;
3211ade2d7dSDavid Daney }
3221ade2d7dSDavid Daney if (eh.ehdr.e_type != ET_EXEC || eh.ehdr.e_machine != EM_MIPS) {
3231ade2d7dSDavid Daney pr_info("Incompatible ELF not MIPS EXEC.");
3241ade2d7dSDavid Daney return false;
3251ade2d7dSDavid Daney }
3261ade2d7dSDavid Daney
3271ade2d7dSDavid Daney if (eh.ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
3281ade2d7dSDavid Daney if (!kvm__arch_get_elf_64_info(&eh.ehdr, fd_kernel, &ei))
3291ade2d7dSDavid Daney return false;
3301ade2d7dSDavid Daney kvm->arch.is64bit = true;
3311ade2d7dSDavid Daney } else {
3321ade2d7dSDavid Daney if (!kvm__arch_get_elf_32_info(&eh.ehdr32, fd_kernel, &ei))
3331ade2d7dSDavid Daney return false;
3341ade2d7dSDavid Daney kvm->arch.is64bit = false;
3351ade2d7dSDavid Daney }
3361ade2d7dSDavid Daney
3371ade2d7dSDavid Daney kvm->arch.entry_point = ei.entry_point;
3381ade2d7dSDavid Daney
3391ade2d7dSDavid Daney if (lseek(fd_kernel, ei.offset, SEEK_SET) < 0)
3401ade2d7dSDavid Daney die_perror("lseek");
3411ade2d7dSDavid Daney
3421ade2d7dSDavid Daney p = guest_flat_to_host(kvm, ei.load_addr);
3431ade2d7dSDavid Daney
3441ade2d7dSDavid Daney pr_info("ELF Loading 0x%lx bytes from 0x%llx to 0x%llx",
34512225973SAndre Przywara (unsigned long)ei.len, (unsigned long long)ei.offset,
34612225973SAndre Przywara (unsigned long long)ei.load_addr);
34712225973SAndre Przywara
34812225973SAndre Przywara if (read_in_full(fd_kernel, p, ei.len) != (ssize_t)ei.len)
3491ade2d7dSDavid Daney die_perror("read");
3501ade2d7dSDavid Daney
3511ade2d7dSDavid Daney return true;
3521ade2d7dSDavid Daney }
3531ade2d7dSDavid Daney
kvm__arch_load_kernel_image(struct kvm * kvm,int fd_kernel,int fd_initrd,const char * kernel_cmdline)354004f7684SAndre Przywara bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
355004f7684SAndre Przywara const char *kernel_cmdline)
356004f7684SAndre Przywara {
357004f7684SAndre Przywara if (fd_initrd != -1) {
358004f7684SAndre Przywara pr_err("Initrd not supported on MIPS.");
359004f7684SAndre Przywara return false;
360004f7684SAndre Przywara }
361004f7684SAndre Przywara
362004f7684SAndre Przywara if (load_elf_binary(kvm, fd_kernel)) {
363004f7684SAndre Przywara kvm__mips_install_cmdline(kvm);
364004f7684SAndre Przywara return true;
365004f7684SAndre Przywara }
366004f7684SAndre Przywara
367004f7684SAndre Przywara return load_flat_binary(kvm, fd_kernel);
368004f7684SAndre Przywara }
369004f7684SAndre Przywara
ioport__map_irq(u8 * irq)3707281a8dbSDavid Daney void ioport__map_irq(u8 *irq)
3717281a8dbSDavid Daney {
3727281a8dbSDavid Daney }
3736f6f384cSAlexandru Elisei
serial8250__inject_sysrq(struct kvm * kvm,char sysrq)3746f6f384cSAlexandru Elisei void serial8250__inject_sysrq(struct kvm *kvm, char sysrq)
3756f6f384cSAlexandru Elisei {
3766f6f384cSAlexandru Elisei }
377