Refactor MIPS' load_elf_binary() implementation by not reading the ELF header itself, but using a pointer to a memory buffer instead. This prepares for removing the need to rewind the image file later. Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> --- mips/kvm.c | 52 +++++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/mips/kvm.c b/mips/kvm.c index 4d08b20..ed81a02 100644 --- a/mips/kvm.c +++ b/mips/kvm.c @@ -282,46 +282,39 @@ static bool kvm__arch_get_elf_32_info(Elf32_Ehdr *ehdr, int fd_kernel, return true; } -static bool load_elf_binary(struct kvm *kvm, int fd_kernel) -{ - union { - Elf64_Ehdr ehdr; - Elf32_Ehdr ehdr32; - } eh; +union ElfHeaders { + Elf64_Ehdr ehdr; + Elf32_Ehdr ehdr32; +}; +static bool load_elf_binary(struct kvm *kvm, int fd_kernel, + union ElfHeaders *eh) +{ size_t nr; char *p; struct kvm__arch_elf_info ei; - if (lseek(fd_kernel, 0, SEEK_SET) < 0) - die_perror("lseek"); - - nr = read(fd_kernel, &eh, sizeof(eh)); - if (nr != sizeof(eh)) { - pr_info("Couldn't read %d bytes for ELF header.", (int)sizeof(eh)); - return false; - } - - if (eh.ehdr.e_ident[EI_MAG0] != ELFMAG0 || - eh.ehdr.e_ident[EI_MAG1] != ELFMAG1 || - eh.ehdr.e_ident[EI_MAG2] != ELFMAG2 || - eh.ehdr.e_ident[EI_MAG3] != ELFMAG3 || - (eh.ehdr.e_ident[EI_CLASS] != ELFCLASS64 && eh.ehdr.e_ident[EI_CLASS] != ELFCLASS32) || - eh.ehdr.e_ident[EI_VERSION] != EV_CURRENT) { + if (eh->ehdr.e_ident[EI_MAG0] != ELFMAG0 || + eh->ehdr.e_ident[EI_MAG1] != ELFMAG1 || + eh->ehdr.e_ident[EI_MAG2] != ELFMAG2 || + eh->ehdr.e_ident[EI_MAG3] != ELFMAG3 || + (eh->ehdr.e_ident[EI_CLASS] != ELFCLASS64 && + eh->ehdr.e_ident[EI_CLASS] != ELFCLASS32) || + eh->ehdr.e_ident[EI_VERSION] != EV_CURRENT) { pr_info("Incompatible ELF header."); return false; } - if (eh.ehdr.e_type != ET_EXEC || eh.ehdr.e_machine != EM_MIPS) { + if (eh->ehdr.e_type != ET_EXEC || eh->ehdr.e_machine != EM_MIPS) { pr_info("Incompatible ELF not MIPS EXEC."); return false; } - if (eh.ehdr.e_ident[EI_CLASS] == ELFCLASS64) { - if (!kvm__arch_get_elf_64_info(&eh.ehdr, fd_kernel, &ei)) + if (eh->ehdr.e_ident[EI_CLASS] == ELFCLASS64) { + if (!kvm__arch_get_elf_64_info(&eh->ehdr, fd_kernel, &ei)) return false; kvm->arch.is64bit = true; } else { - if (!kvm__arch_get_elf_32_info(&eh.ehdr32, fd_kernel, &ei)) + if (!kvm__arch_get_elf_32_info(&eh->ehdr32, fd_kernel, &ei)) return false; kvm->arch.is64bit = false; } @@ -334,7 +327,8 @@ static bool load_elf_binary(struct kvm *kvm, int fd_kernel) p = guest_flat_to_host(kvm, ei.load_addr); pr_info("ELF Loading 0x%lx bytes from 0x%llx to 0x%llx", - (unsigned long)ei.len, (unsigned long long)ei.offset, (unsigned long long)ei.load_addr); + (unsigned long)ei.len, (unsigned long long)ei.offset, + (unsigned long long)ei.load_addr); do { nr = read(fd_kernel, p, ei.len); if (nr < 0) @@ -349,12 +343,16 @@ static bool load_elf_binary(struct kvm *kvm, int fd_kernel) bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline) { + union ElfHeaders eh; + if (fd_initrd != -1) { pr_err("Initrd not supported on MIPS."); return false; } - if (load_elf_binary(kvm, fd_kernel)) { + read_in_full(fd_kernel, &eh, sizeof(eh)); + + if (load_elf_binary(kvm, fd_kernel, &eh)) { kvm__mips_install_cmdline(kvm); return true; } -- 2.3.5 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html