diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm index 20e104f48c..77f15ba07b 100644 --- a/gnu/services/virtualization.scm +++ b/gnu/services/virtualization.scm @@ -23,6 +23,7 @@ #:use-module (gnu bootloader grub) #:use-module (gnu image) #:use-module (gnu packages admin) + #:use-module (gnu packages cross-base) #:use-module (gnu packages ssh) #:use-module (gnu packages virtualization) #:use-module (gnu services base) @@ -554,12 +555,13 @@ potential infinite waits blocking libvirt.")) ;; Platforms that QEMU can emulate. (define-record-type - (qemu-platform name family magic mask) + (qemu-platform name family register-width magic mask) qemu-platform? - (name qemu-platform-name) ;string - (family qemu-platform-family) ;string - (magic qemu-platform-magic) ;bytevector - (mask qemu-platform-mask)) ;bytevector + (name qemu-platform-name) ;string + (family qemu-platform-family) ;string + (register-width qemu-platform-register-width) ;int, in bits + (magic qemu-platform-magic) ;bytevector + (mask qemu-platform-mask)) ;bytevector (define-syntax bv (lambda (s) @@ -576,123 +578,123 @@ potential infinite waits blocking libvirt.")) ;;; 'scripts/qemu-binfmt-conf.sh' in QEMU. (define %i386 - (qemu-platform "i386" "i386" + (qemu-platform "i386" "i386" 32 (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00") (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %i486 - (qemu-platform "i486" "i386" + (qemu-platform "i486" "i386" 32 (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00") (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %alpha - (qemu-platform "alpha" "alpha" + (qemu-platform "alpha" "alpha" 64 (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90") (bv "\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %arm - (qemu-platform "arm" "arm" + (qemu-platform "arm" "arm" 32 (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %armeb - (qemu-platform "armeb" "arm" + (qemu-platform "armeb" "arm" 32 (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %sparc - (qemu-platform "sparc" "sparc" + (qemu-platform "sparc" "sparc" 32 ; FIXME check (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02") (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %sparc32plus - (qemu-platform "sparc32plus" "sparc" + (qemu-platform "sparc32plus" "sparc" 32 ; FIXME check (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12") (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %ppc - (qemu-platform "ppc" "ppc" + (qemu-platform "ppc" "ppc" 32 (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %ppc64 - (qemu-platform "ppc64" "ppc" + (qemu-platform "ppc64" "ppc" 64 (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %ppc64le - (qemu-platform "ppc64le" "ppcle" + (qemu-platform "ppc64le" "ppcle" 64 (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00"))) (define %m68k - (qemu-platform "m68k" "m68k" + (qemu-platform "m68k" "m68k" 32 (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04") (bv "\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) ;; XXX: We could use the other endianness on a MIPS host. (define %mips - (qemu-platform "mips" "mips" + (qemu-platform "mips" "mips" 32 (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %mipsel - (qemu-platform "mipsel" "mips" + (qemu-platform "mipsel" "mips" 32 (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %mipsn32 - (qemu-platform "mipsn32" "mips" + (qemu-platform "mipsn32" "mips" 32 ; FIXME check (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %mipsn32el - (qemu-platform "mipsn32el" "mips" + (qemu-platform "mipsn32el" "mips" 32 ; FIXME check (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %mips64 - (qemu-platform "mips64" "mips" + (qemu-platform "mips64" "mips" 64 (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %mips64el - (qemu-platform "mips64el" "mips" + (qemu-platform "mips64el" "mips" 64 (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %riscv32 - (qemu-platform "riscv32" "riscv" + (qemu-platform "riscv32" "riscv" 32 ; FIXME (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %riscv64 - (qemu-platform "riscv64" "riscv" + (qemu-platform "riscv64" "riscv" 64 (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %sh4 - (qemu-platform "sh4" "sh4" + (qemu-platform "sh4" "sh4" 32 (bv "\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %sh4eb - (qemu-platform "sh4eb" "sh4" + (qemu-platform "sh4eb" "sh4" 32 (bv "\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a") (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %s390x - (qemu-platform "s390x" "s390x" + (qemu-platform "s390x" "s390x" 64 (bv "\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16") (bv "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) (define %aarch64 - (qemu-platform "aarch64" "arm" + (qemu-platform "aarch64" "arm" 64 (bv "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"))) (define %hppa - (qemu-platform "hppa" "hppa" + (qemu-platform "hppa" "hppa" 32 (bv "\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f") (bv "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff"))) @@ -712,12 +714,48 @@ potential infinite waits blocking libvirt.")) qemu-binfmt-configuration make-qemu-binfmt-configuration qemu-binfmt-configuration? (qemu qemu-binfmt-configuration-qemu - (default qemu)) + (default qemu-minimal)) (platforms qemu-binfmt-configuration-platforms (default '())) ;safest default (guix-support? qemu-binfmt-configuration-guix-support? (default #f))) +(define (register-width system) + (match (%current-system) + ("i686-linux" 32) + ("armhf-linux" 32) + ("aarch64-linux" 64) + ("x86_64-linux" 64))) + +(define (closest-cross-compiled-qemu qemu target-bits) + "Cross-compile QEMU for the given TARGET-BITS platform that is closest to +the actual host architecture, if possible. This is in order to prevent +https://lore.kernel.org/lkml/20181229015453.GA6310@bombadil.infradead.org/T/" + (define (cross-compiled-qemu target) + (package + (inherit qemu) + (arguments + (substitute-keyword-arguments (package-arguments qemu) + ((#:configure-flags flags) + `(cons ,(string-append "--cross-prefix=" target "-") + ,flags)))) + (native-inputs + `(("cross-gcc" ,(cross-gcc target)) + ("cross-binutils" ,(cross-binutils target)) + ,@(package-native-inputs qemu))))) + (match target-bits + (64 qemu) + (32 (match (register-width (%current-system)) + (32 qemu) + (64 (match (%current-system) + ("x86_64-linux" + (cross-compiled-qemu (nix-system->gnu-triplet "i686-linux"))) + ("aarch64-linux" + (cross-compiled-qemu "arm-linux-gnueabihf")) + (_ (begin + ;; TODO: Print warning + qemu)))))))) + (define (qemu-platform->binfmt qemu platform) "Return a gexp that evaluates to a binfmt string for PLATFORM, using the given QEMU package." @@ -732,12 +770,13 @@ given QEMU package." (bytevector->u8-list bv)))) (match platform - (($ name family magic mask) + (($ name family register-width magic mask) ;; See 'Documentation/binfmt_misc.txt' in the kernel. #~(string-append ":qemu-" #$name ":M::" #$(bytevector->binfmt-string magic) ":" #$(bytevector->binfmt-string mask) - ":" #$(file-append qemu "/bin/qemu-" name) + ":" #$(file-append (closest-cross-compiled-qemu qemu register-width) + "/bin/qemu-" name) ":" ;FLAGS go here ))))