binfmt: Add --ignore-family option
authorAndrea Bolognani <abologna@redhat.com>
Mon, 27 Jan 2025 18:29:24 +0000 (19:29 +0100)
committerAlistair Francis <alistair.francis@wdc.com>
Tue, 4 Mar 2025 05:42:54 +0000 (15:42 +1000)
Until now, the script has worked under the assumption that a
host CPU can run binaries targeting any CPU in the same family.
That's a fair enough assumption when it comes to running i386
binaries on x86_64, but it doesn't quite apply in the general
case.

For example, while riscv64 CPUs could theoretically run riscv32
applications natively, in practice there exist few (if any?)
CPUs that implement the necessary silicon; moreover, even if you
had one such CPU, your host OS would most likely not have
enabled the necessary kernel bits.

This new option gives distro packagers the ability to opt out of
the assumption, likely on a per-architecture basis, and make
things work out of the box for a larger fraction of their user
base.

As an interesting side effect, this makes it possible to enable
execution of 64-bit binaries on 32-bit CPUs of the same family,
which is a perfectly valid use case that apparently hadn't been
considered until now.

Link: https://src.fedoraproject.org/rpms/qemu/pull-request/72
Thanks: David Abdurachmanov <davidlt@rivosinc.com>
Thanks: Daniel P. BerrangĂ© <berrange@redhat.com>
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-ID: <20250127182924.103510-4-abologna@redhat.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
scripts/qemu-binfmt-conf.sh

index 8d9136a29f10c942d1b07892cce00c9b31de6181..5fd462b1d1c87b606f3c2c89087907aa1c56bcf5 100755 (executable)
@@ -205,6 +205,9 @@ Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian][--systemd CPU]
        --persistent:    if yes, the interpreter is loaded when binfmt is
                         configured and remains in memory. All future uses
                         are cloned from the open file.
+       --ignore-family: if yes, it is assumed that the host CPU (e.g. riscv64)
+                        can't natively run programs targeting a CPU that is
+                        part of the same family (e.g. riscv32).
        --preserve-argv0 preserve argv[0]
 
     To import templates with update-binfmts, use :
@@ -337,7 +340,12 @@ qemu_set_binfmts() {
         fi
 
         if [ "$host_family" = "$family" ] ; then
-            continue
+            # When --ignore-family is used, we have to generate rules even
+            # for targets that are in the same family as the host CPU. The
+            # only exception is of course when the CPU types exactly match
+            if [ "$target" = "$host_cpu" ] || [ "$IGNORE_FAMILY" = "no" ] ; then
+                continue
+            fi
         fi
 
         $BINFMT_SET
@@ -355,10 +363,11 @@ CREDENTIAL=no
 PERSISTENT=no
 PRESERVE_ARG0=no
 QEMU_SUFFIX=""
+IGNORE_FAMILY=no
 
 _longopts="debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,\
-persistent:,preserve-argv0:"
-options=$(getopt -o ds:Q:S:e:hc:p:g:F: -l ${_longopts} -- "$@")
+persistent:,preserve-argv0:,ignore-family:"
+options=$(getopt -o ds:Q:S:e:hc:p:g:F:i: -l ${_longopts} -- "$@")
 eval set -- "$options"
 
 while true ; do
@@ -418,6 +427,10 @@ while true ; do
         shift
         PRESERVE_ARG0="$1"
         ;;
+    -i|--ignore-family)
+        shift
+        IGNORE_FAMILY="$1"
+        ;;
     *)
         break
         ;;