xref: /kvmtool/mips/kvm.c (revision 6f6f384cef27372b746158951c5ba011ca914acd)
1*6f6f384cSAlexandru 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 
167281a8dbSDavid Daney void kvm__arch_read_term(struct kvm *kvm)
177281a8dbSDavid Daney {
187281a8dbSDavid Daney 	virtio_console__inject_interrupt(kvm);
197281a8dbSDavid Daney }
207281a8dbSDavid Daney 
217281a8dbSDavid Daney void kvm__init_ram(struct kvm *kvm)
227281a8dbSDavid Daney {
237281a8dbSDavid Daney 	u64	phys_start, phys_size;
247281a8dbSDavid Daney 	void	*host_mem;
257281a8dbSDavid Daney 
2657896feeSAndreas Herrmann 	if (kvm->ram_size <= KVM_MMIO_START) {
2757896feeSAndreas Herrmann 		/* one region for all memory */
287281a8dbSDavid Daney 		phys_start = 0;
297281a8dbSDavid Daney 		phys_size  = kvm->ram_size;
307281a8dbSDavid Daney 		host_mem   = kvm->ram_start;
317281a8dbSDavid Daney 
328f46c736SJean-Philippe Brucker 		kvm__register_ram(kvm, phys_start, phys_size, host_mem);
3357896feeSAndreas Herrmann 	} else {
3457896feeSAndreas Herrmann 		/* one region for memory that fits below MMIO range */
3557896feeSAndreas Herrmann 		phys_start = 0;
3657896feeSAndreas Herrmann 		phys_size  = KVM_MMIO_START;
3757896feeSAndreas Herrmann 		host_mem   = kvm->ram_start;
3857896feeSAndreas Herrmann 
398f46c736SJean-Philippe Brucker 		kvm__register_ram(kvm, phys_start, phys_size, host_mem);
4057896feeSAndreas Herrmann 
4157896feeSAndreas Herrmann 		/* one region for rest of memory */
4257896feeSAndreas Herrmann 		phys_start = KVM_MMIO_START + KVM_MMIO_SIZE;
4357896feeSAndreas Herrmann 		phys_size  = kvm->ram_size - KVM_MMIO_START;
4457896feeSAndreas Herrmann 		host_mem   = kvm->ram_start + KVM_MMIO_START;
4557896feeSAndreas Herrmann 
468f46c736SJean-Philippe Brucker 		kvm__register_ram(kvm, phys_start, phys_size, host_mem);
4757896feeSAndreas Herrmann 	}
487281a8dbSDavid Daney }
497281a8dbSDavid Daney 
507281a8dbSDavid Daney void kvm__arch_delete_ram(struct kvm *kvm)
517281a8dbSDavid Daney {
527281a8dbSDavid Daney 	munmap(kvm->ram_start, kvm->ram_size);
537281a8dbSDavid Daney }
547281a8dbSDavid Daney 
557281a8dbSDavid Daney void kvm__arch_set_cmdline(char *cmdline, bool video)
567281a8dbSDavid Daney {
577281a8dbSDavid Daney 
587281a8dbSDavid Daney }
597281a8dbSDavid Daney 
607281a8dbSDavid Daney /* Architecture-specific KVM init */
617281a8dbSDavid Daney void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
627281a8dbSDavid Daney {
637281a8dbSDavid Daney 	int ret;
647281a8dbSDavid Daney 
657281a8dbSDavid Daney 	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
667281a8dbSDavid Daney 	kvm->ram_size = ram_size;
677281a8dbSDavid Daney 
687281a8dbSDavid Daney 	if (kvm->ram_start == MAP_FAILED)
697281a8dbSDavid Daney 		die("out of memory");
707281a8dbSDavid Daney 
717281a8dbSDavid Daney 	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
727281a8dbSDavid Daney 
737281a8dbSDavid Daney 	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
747281a8dbSDavid Daney 	if (ret < 0)
757281a8dbSDavid Daney 		die_perror("KVM_CREATE_IRQCHIP ioctl");
767281a8dbSDavid Daney }
777281a8dbSDavid Daney 
787281a8dbSDavid Daney void kvm__irq_line(struct kvm *kvm, int irq, int level)
797281a8dbSDavid Daney {
807281a8dbSDavid Daney 	struct kvm_irq_level irq_level;
817281a8dbSDavid Daney 	int ret;
827281a8dbSDavid Daney 
837281a8dbSDavid Daney 	irq_level.irq = irq;
847281a8dbSDavid Daney 	irq_level.level = level ? 1 : 0;
857281a8dbSDavid Daney 
867281a8dbSDavid Daney 	ret = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level);
877281a8dbSDavid Daney 	if (ret < 0)
887281a8dbSDavid Daney 		die_perror("KVM_IRQ_LINE ioctl");
897281a8dbSDavid Daney }
907281a8dbSDavid Daney 
917281a8dbSDavid Daney void kvm__irq_trigger(struct kvm *kvm, int irq)
927281a8dbSDavid Daney {
937281a8dbSDavid Daney 	struct kvm_irq_level irq_level;
947281a8dbSDavid Daney 	int ret;
957281a8dbSDavid Daney 
967281a8dbSDavid Daney 	irq_level.irq = irq;
977281a8dbSDavid Daney 	irq_level.level = 1;
987281a8dbSDavid Daney 
997281a8dbSDavid Daney 	ret = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level);
1007281a8dbSDavid Daney 	if (ret < 0)
1017281a8dbSDavid Daney 		die_perror("KVM_IRQ_LINE ioctl");
1027281a8dbSDavid Daney }
1037281a8dbSDavid Daney 
1047281a8dbSDavid Daney bool kvm__arch_cpu_supports_vm(void)
1057281a8dbSDavid Daney {
1067281a8dbSDavid Daney 	return true;
1077281a8dbSDavid Daney }
1087281a8dbSDavid Daney bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
1097281a8dbSDavid Daney {
1107281a8dbSDavid Daney 	return false;
1117281a8dbSDavid Daney }
1127281a8dbSDavid Daney int kvm__arch_setup_firmware(struct kvm *kvm)
1137281a8dbSDavid Daney {
1147281a8dbSDavid Daney 	return 0;
1157281a8dbSDavid Daney }
1167281a8dbSDavid Daney 
1171ade2d7dSDavid Daney static void kvm__mips_install_cmdline(struct kvm *kvm)
1181ade2d7dSDavid Daney {
1191ade2d7dSDavid Daney 	char *p = kvm->ram_start;
1201ade2d7dSDavid Daney 	u64 cmdline_offset = 0x2000;
1211ade2d7dSDavid Daney 	u64 argv_start = 0x3000;
1221ade2d7dSDavid Daney 	u64 argv_offset = argv_start;
1231ade2d7dSDavid Daney 	u64 argc = 0;
1241ade2d7dSDavid Daney 
12557896feeSAndreas Herrmann 
12657896feeSAndreas Herrmann 	if ((u64) kvm->ram_size <= KVM_MMIO_START)
1271ade2d7dSDavid Daney 		sprintf(p + cmdline_offset, "mem=0x%llx@0 ",
1281ade2d7dSDavid Daney 			(unsigned long long)kvm->ram_size);
12957896feeSAndreas Herrmann 	else
13057896feeSAndreas Herrmann 		sprintf(p + cmdline_offset, "mem=0x%llx@0 mem=0x%llx@0x%llx ",
13157896feeSAndreas Herrmann 			(unsigned long long)KVM_MMIO_START,
13257896feeSAndreas Herrmann 			(unsigned long long)kvm->ram_size - KVM_MMIO_START,
13357896feeSAndreas Herrmann 			(unsigned long long)(KVM_MMIO_START + KVM_MMIO_SIZE));
1341ade2d7dSDavid Daney 
1355613ae26SAlexandru Elisei 	if (kvm->cfg.real_cmdline)
1361ade2d7dSDavid Daney 		strcat(p + cmdline_offset, kvm->cfg.real_cmdline); /* maximum size is 2K */
1371ade2d7dSDavid Daney 
1381ade2d7dSDavid Daney 	while (p[cmdline_offset]) {
1391ade2d7dSDavid Daney 		if (!isspace(p[cmdline_offset])) {
1401ade2d7dSDavid Daney 			if (kvm->arch.is64bit) {
1411ade2d7dSDavid Daney 				*(u64 *)(p + argv_offset) = 0xffffffff80000000ull + cmdline_offset;
1421ade2d7dSDavid Daney 				argv_offset += sizeof(u64);
1431ade2d7dSDavid Daney 			} else {
1441ade2d7dSDavid Daney 				*(u32 *)(p + argv_offset) = 0x80000000u + cmdline_offset;
1451ade2d7dSDavid Daney 				argv_offset += sizeof(u32);
1461ade2d7dSDavid Daney 			}
1471ade2d7dSDavid Daney 			argc++;
1481ade2d7dSDavid Daney 			while(p[cmdline_offset] && !isspace(p[cmdline_offset]))
1491ade2d7dSDavid Daney 				cmdline_offset++;
1501ade2d7dSDavid Daney 			continue;
1511ade2d7dSDavid Daney 		}
1521ade2d7dSDavid Daney 		/* Must be a space character skip over these*/
1531ade2d7dSDavid Daney 		while(p[cmdline_offset] && isspace(p[cmdline_offset])) {
1541ade2d7dSDavid Daney 			p[cmdline_offset] = 0;
1551ade2d7dSDavid Daney 			cmdline_offset++;
1561ade2d7dSDavid Daney 		}
1571ade2d7dSDavid Daney 	}
1581ade2d7dSDavid Daney 	kvm->arch.argc = argc;
1591ade2d7dSDavid Daney 	kvm->arch.argv = 0xffffffff80000000ull + argv_start;
1601ade2d7dSDavid Daney }
1611ade2d7dSDavid Daney 
1627281a8dbSDavid Daney /* Load at the 1M point. */
1637281a8dbSDavid Daney #define KERNEL_LOAD_ADDR 0x1000000
164004f7684SAndre Przywara 
165004f7684SAndre Przywara static bool load_flat_binary(struct kvm *kvm, int fd_kernel)
1667281a8dbSDavid Daney {
1677281a8dbSDavid Daney 	void *p;
1687281a8dbSDavid Daney 	void *k_start;
16912225973SAndre Przywara 	ssize_t kernel_size;
1707281a8dbSDavid Daney 
1717281a8dbSDavid Daney 	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
1727281a8dbSDavid Daney 		die_perror("lseek");
1737281a8dbSDavid Daney 
1747281a8dbSDavid Daney 	p = k_start = guest_flat_to_host(kvm, KERNEL_LOAD_ADDR);
1757281a8dbSDavid Daney 
17612225973SAndre Przywara 	kernel_size = read_file(fd_kernel, p,
17712225973SAndre Przywara 				kvm->cfg.ram_size - KERNEL_LOAD_ADDR);
17812225973SAndre Przywara 	if (kernel_size == -1) {
17912225973SAndre Przywara 		if (errno == ENOMEM)
18012225973SAndre Przywara 			die("kernel too big for guest memory");
18112225973SAndre Przywara 		else
18212225973SAndre Przywara 			die_perror("kernel read");
18312225973SAndre Przywara 	}
1847281a8dbSDavid Daney 
1857281a8dbSDavid Daney 	kvm->arch.is64bit = true;
1867281a8dbSDavid Daney 	kvm->arch.entry_point = 0xffffffff81000000ull;
1877281a8dbSDavid Daney 
18812225973SAndre Przywara 	pr_info("Loaded kernel to 0x%x (%zd bytes)", KERNEL_LOAD_ADDR,
18912225973SAndre Przywara 		kernel_size);
1907281a8dbSDavid Daney 
1917281a8dbSDavid Daney 	return true;
1927281a8dbSDavid Daney }
1937281a8dbSDavid Daney 
1941ade2d7dSDavid Daney struct kvm__arch_elf_info {
1951ade2d7dSDavid Daney 	u64 load_addr;
1961ade2d7dSDavid Daney 	u64 entry_point;
1971ade2d7dSDavid Daney 	size_t len;
1981ade2d7dSDavid Daney 	size_t offset;
1991ade2d7dSDavid Daney };
2001ade2d7dSDavid Daney 
2011ade2d7dSDavid Daney static bool kvm__arch_get_elf_64_info(Elf64_Ehdr *ehdr, int fd_kernel,
2021ade2d7dSDavid Daney 				      struct kvm__arch_elf_info *ei)
2031ade2d7dSDavid Daney {
2041ade2d7dSDavid Daney 	int i;
2051ade2d7dSDavid Daney 	Elf64_Phdr phdr;
2061ade2d7dSDavid Daney 
2071ade2d7dSDavid Daney 	if (ehdr->e_phentsize != sizeof(phdr)) {
2081ade2d7dSDavid Daney 		pr_info("Incompatible ELF PHENTSIZE %d", ehdr->e_phentsize);
2091ade2d7dSDavid Daney 		return false;
2101ade2d7dSDavid Daney 	}
2111ade2d7dSDavid Daney 
2121ade2d7dSDavid Daney 	ei->entry_point = ehdr->e_entry;
2131ade2d7dSDavid Daney 
2141ade2d7dSDavid Daney 	if (lseek(fd_kernel, ehdr->e_phoff, SEEK_SET) < 0)
2151ade2d7dSDavid Daney 		die_perror("lseek");
2161ade2d7dSDavid Daney 
2171ade2d7dSDavid Daney 	phdr.p_type = PT_NULL;
2181ade2d7dSDavid Daney 	for (i = 0; i < ehdr->e_phnum; i++) {
21912225973SAndre Przywara 		if (read_in_full(fd_kernel, &phdr, sizeof(phdr)) != sizeof(phdr)) {
2201ade2d7dSDavid Daney 			pr_info("Couldn't read %d bytes for ELF PHDR.", (int)sizeof(phdr));
2211ade2d7dSDavid Daney 			return false;
2221ade2d7dSDavid Daney 		}
2231ade2d7dSDavid Daney 		if (phdr.p_type == PT_LOAD)
2241ade2d7dSDavid Daney 			break;
2251ade2d7dSDavid Daney 	}
2261ade2d7dSDavid Daney 	if (phdr.p_type != PT_LOAD) {
2271ade2d7dSDavid Daney 		pr_info("No PT_LOAD Program Header found.");
2281ade2d7dSDavid Daney 		return false;
2291ade2d7dSDavid Daney 	}
2301ade2d7dSDavid Daney 
2311ade2d7dSDavid Daney 	ei->load_addr = phdr.p_paddr;
2321ade2d7dSDavid Daney 
2331ade2d7dSDavid Daney 	if ((ei->load_addr & 0xffffffffc0000000ull) == 0xffffffff80000000ull)
2341ade2d7dSDavid Daney 		ei->load_addr &= 0x1ffffffful; /* Convert KSEG{0,1} to physical. */
2351ade2d7dSDavid Daney 	if ((ei->load_addr & 0xc000000000000000ull) == 0x8000000000000000ull)
2361ade2d7dSDavid Daney 		ei->load_addr &= 0x07ffffffffffffffull; /* Convert XKPHYS to pysical */
2371ade2d7dSDavid Daney 
2381ade2d7dSDavid Daney 
2391ade2d7dSDavid Daney 	ei->len = phdr.p_filesz;
2401ade2d7dSDavid Daney 	ei->offset = phdr.p_offset;
2411ade2d7dSDavid Daney 
2421ade2d7dSDavid Daney 	return true;
2431ade2d7dSDavid Daney }
2441ade2d7dSDavid Daney 
2451ade2d7dSDavid Daney static bool kvm__arch_get_elf_32_info(Elf32_Ehdr *ehdr, int fd_kernel,
2461ade2d7dSDavid Daney 				      struct kvm__arch_elf_info *ei)
2471ade2d7dSDavid Daney {
2481ade2d7dSDavid Daney 	int i;
2491ade2d7dSDavid Daney 	Elf32_Phdr phdr;
2501ade2d7dSDavid Daney 
2511ade2d7dSDavid Daney 	if (ehdr->e_phentsize != sizeof(phdr)) {
2521ade2d7dSDavid Daney 		pr_info("Incompatible ELF PHENTSIZE %d", ehdr->e_phentsize);
2531ade2d7dSDavid Daney 		return false;
2541ade2d7dSDavid Daney 	}
2551ade2d7dSDavid Daney 
2561ade2d7dSDavid Daney 	ei->entry_point = (s64)((s32)ehdr->e_entry);
2571ade2d7dSDavid Daney 
2581ade2d7dSDavid Daney 	if (lseek(fd_kernel, ehdr->e_phoff, SEEK_SET) < 0)
2591ade2d7dSDavid Daney 		die_perror("lseek");
2601ade2d7dSDavid Daney 
2611ade2d7dSDavid Daney 	phdr.p_type = PT_NULL;
2621ade2d7dSDavid Daney 	for (i = 0; i < ehdr->e_phnum; i++) {
26312225973SAndre Przywara 		if (read_in_full(fd_kernel, &phdr, sizeof(phdr)) != sizeof(phdr)) {
2641ade2d7dSDavid Daney 			pr_info("Couldn't read %d bytes for ELF PHDR.", (int)sizeof(phdr));
2651ade2d7dSDavid Daney 			return false;
2661ade2d7dSDavid Daney 		}
2671ade2d7dSDavid Daney 		if (phdr.p_type == PT_LOAD)
2681ade2d7dSDavid Daney 			break;
2691ade2d7dSDavid Daney 	}
2701ade2d7dSDavid Daney 	if (phdr.p_type != PT_LOAD) {
2711ade2d7dSDavid Daney 		pr_info("No PT_LOAD Program Header found.");
2721ade2d7dSDavid Daney 		return false;
2731ade2d7dSDavid Daney 	}
2741ade2d7dSDavid Daney 
2751ade2d7dSDavid Daney 	ei->load_addr = (s64)((s32)phdr.p_paddr);
2761ade2d7dSDavid Daney 
2771ade2d7dSDavid Daney 	if ((ei->load_addr & 0xffffffffc0000000ull) == 0xffffffff80000000ull)
2781ade2d7dSDavid Daney 		ei->load_addr &= 0x1fffffffull; /* Convert KSEG{0,1} to physical. */
2791ade2d7dSDavid Daney 
2801ade2d7dSDavid Daney 	ei->len = phdr.p_filesz;
2811ade2d7dSDavid Daney 	ei->offset = phdr.p_offset;
2821ade2d7dSDavid Daney 
2831ade2d7dSDavid Daney 	return true;
2841ade2d7dSDavid Daney }
2851ade2d7dSDavid Daney 
286004f7684SAndre Przywara static bool load_elf_binary(struct kvm *kvm, int fd_kernel)
2871ade2d7dSDavid Daney {
2881ade2d7dSDavid Daney 	union {
2891ade2d7dSDavid Daney 		Elf64_Ehdr ehdr;
2901ade2d7dSDavid Daney 		Elf32_Ehdr ehdr32;
2911ade2d7dSDavid Daney 	} eh;
2921ade2d7dSDavid Daney 
2931ade2d7dSDavid Daney 	size_t nr;
2941ade2d7dSDavid Daney 	char *p;
2951ade2d7dSDavid Daney 	struct kvm__arch_elf_info ei;
2961ade2d7dSDavid Daney 
2971ade2d7dSDavid Daney 	nr = read(fd_kernel, &eh, sizeof(eh));
2981ade2d7dSDavid Daney 	if (nr != sizeof(eh)) {
2991ade2d7dSDavid Daney 		pr_info("Couldn't read %d bytes for ELF header.", (int)sizeof(eh));
3001ade2d7dSDavid Daney 		return false;
3011ade2d7dSDavid Daney 	}
3021ade2d7dSDavid Daney 
3031ade2d7dSDavid Daney 	if (eh.ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
3041ade2d7dSDavid Daney 	    eh.ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
3051ade2d7dSDavid Daney 	    eh.ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
3061ade2d7dSDavid Daney 	    eh.ehdr.e_ident[EI_MAG3] != ELFMAG3 ||
3071ade2d7dSDavid Daney 	    (eh.ehdr.e_ident[EI_CLASS] != ELFCLASS64 && eh.ehdr.e_ident[EI_CLASS] != ELFCLASS32) ||
3081ade2d7dSDavid Daney 	    eh.ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
3091ade2d7dSDavid Daney 		pr_info("Incompatible ELF header.");
3101ade2d7dSDavid Daney 		return false;
3111ade2d7dSDavid Daney 	}
3121ade2d7dSDavid Daney 	if (eh.ehdr.e_type != ET_EXEC || eh.ehdr.e_machine != EM_MIPS) {
3131ade2d7dSDavid Daney 		pr_info("Incompatible ELF not MIPS EXEC.");
3141ade2d7dSDavid Daney 		return false;
3151ade2d7dSDavid Daney 	}
3161ade2d7dSDavid Daney 
3171ade2d7dSDavid Daney 	if (eh.ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
3181ade2d7dSDavid Daney 		if (!kvm__arch_get_elf_64_info(&eh.ehdr, fd_kernel, &ei))
3191ade2d7dSDavid Daney 			return false;
3201ade2d7dSDavid Daney 		kvm->arch.is64bit = true;
3211ade2d7dSDavid Daney 	} else {
3221ade2d7dSDavid Daney 		if (!kvm__arch_get_elf_32_info(&eh.ehdr32, fd_kernel, &ei))
3231ade2d7dSDavid Daney 			return false;
3241ade2d7dSDavid Daney 		kvm->arch.is64bit = false;
3251ade2d7dSDavid Daney 	}
3261ade2d7dSDavid Daney 
3271ade2d7dSDavid Daney 	kvm->arch.entry_point = ei.entry_point;
3281ade2d7dSDavid Daney 
3291ade2d7dSDavid Daney 	if (lseek(fd_kernel, ei.offset, SEEK_SET) < 0)
3301ade2d7dSDavid Daney 		die_perror("lseek");
3311ade2d7dSDavid Daney 
3321ade2d7dSDavid Daney 	p = guest_flat_to_host(kvm, ei.load_addr);
3331ade2d7dSDavid Daney 
3341ade2d7dSDavid Daney 	pr_info("ELF Loading 0x%lx bytes from 0x%llx to 0x%llx",
33512225973SAndre Przywara 		(unsigned long)ei.len, (unsigned long long)ei.offset,
33612225973SAndre Przywara 		(unsigned long long)ei.load_addr);
33712225973SAndre Przywara 
33812225973SAndre Przywara 	if (read_in_full(fd_kernel, p, ei.len) != (ssize_t)ei.len)
3391ade2d7dSDavid Daney 		die_perror("read");
3401ade2d7dSDavid Daney 
3411ade2d7dSDavid Daney 	return true;
3421ade2d7dSDavid Daney }
3431ade2d7dSDavid Daney 
344004f7684SAndre Przywara bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
345004f7684SAndre Przywara 				 const char *kernel_cmdline)
346004f7684SAndre Przywara {
347004f7684SAndre Przywara 	if (fd_initrd != -1) {
348004f7684SAndre Przywara 		pr_err("Initrd not supported on MIPS.");
349004f7684SAndre Przywara 		return false;
350004f7684SAndre Przywara 	}
351004f7684SAndre Przywara 
352004f7684SAndre Przywara 	if (load_elf_binary(kvm, fd_kernel)) {
353004f7684SAndre Przywara 		kvm__mips_install_cmdline(kvm);
354004f7684SAndre Przywara 		return true;
355004f7684SAndre Przywara 	}
356004f7684SAndre Przywara 
357004f7684SAndre Przywara 	return load_flat_binary(kvm, fd_kernel);
358004f7684SAndre Przywara }
359004f7684SAndre Przywara 
3607281a8dbSDavid Daney void ioport__map_irq(u8 *irq)
3617281a8dbSDavid Daney {
3627281a8dbSDavid Daney }
363*6f6f384cSAlexandru Elisei 
364*6f6f384cSAlexandru Elisei void serial8250__inject_sysrq(struct kvm *kvm, char sysrq)
365*6f6f384cSAlexandru Elisei {
366*6f6f384cSAlexandru Elisei }
367