From 864469531c5290a9b3df4ce994cbc9384ae6c7c9 Mon Sep 17 00:00:00 2001 From: yarl Date: Thu, 1 Oct 2020 23:55:23 +0200 Subject: [PATCH] pmbootstrap qemu: add aarch64 big/little hack (MR 1983) Workaround for qemu failing with: kvm_arm_vcpu_init failed: invalid argument. Related: https://bugs.linaro.org/show_bug.cgi?id=1443 --- pmb/parse/__init__.py | 1 + pmb/parse/cpuinfo.py | 32 ++++++++++++++++++++++++++++++++ pmb/qemu/run.py | 24 +++++++++++++++++++++--- 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 pmb/parse/cpuinfo.py diff --git a/pmb/parse/__init__.py b/pmb/parse/__init__.py index 4205c18a..46e73f7f 100644 --- a/pmb/parse/__init__.py +++ b/pmb/parse/__init__.py @@ -7,4 +7,5 @@ from pmb.parse.binfmt_info import binfmt_info from pmb.parse.deviceinfo import deviceinfo from pmb.parse.kconfig import check from pmb.parse.bootimg import bootimg +from pmb.parse.cpuinfo import arm_big_little_first_group_ncpus import pmb.parse.arch diff --git a/pmb/parse/cpuinfo.py b/pmb/parse/cpuinfo.py new file mode 100644 index 00000000..3f08344a --- /dev/null +++ b/pmb/parse/cpuinfo.py @@ -0,0 +1,32 @@ +# Copyright 2020 Lary Gibaud +# SPDX-License-Identifier: GPL-3.0-or-later +import re + + +def arm_big_little_first_group_ncpus(): + """ + Infer from /proc/cpuinfo on aarch64 if this is a big/little architecture + (if there is different processor models) and the number of cores in the + first model group. + https://en.wikipedia.org/wiki/ARM_big.LITTLE + + :returns: the number of cores of the first model in the order given by + linux or None if not big/little architecture + """ + pattern = re.compile(r"^CPU part\s*: (\w+)$") + counter = 0 + part = None + + with open('/proc/cpuinfo', 'r') as cpuinfo: + for line in cpuinfo: + match = pattern.match(line) + if match: + grp = match.group(1) + if not part: + part = grp + counter += 1 + elif part == grp: + counter += 1 + else: + return counter + return None diff --git a/pmb/qemu/run.py b/pmb/qemu/run.py index 76f81064..fc379c13 100644 --- a/pmb/qemu/run.py +++ b/pmb/qemu/run.py @@ -15,6 +15,7 @@ import pmb.chroot.initfs import pmb.config import pmb.helpers.run import pmb.parse.arch +import pmb.parse.cpuinfo def system_image(args): @@ -84,6 +85,7 @@ def command_qemu(args, arch, img_path): suffix = "rootfs_" + args.device rootfs = args.work + "/chroot_" + suffix flavor = pmb.chroot.other.kernel_flavors_installed(args, suffix)[0] + ncpus = os.cpu_count() if args.host_qemu: qemu_bin = which_qemu(args, arch) @@ -102,8 +104,23 @@ def command_qemu(args, arch, img_path): "XDG_DATA_DIRS": rootfs_native + "/usr/local/share:" + rootfs_native + "/usr/share"}) - command = [rootfs_native + "/lib/ld-musl-" + - args.arch_native + ".so.1"] + command = [] + if args.arch_native in ["aarch64", "armv7"]: + # Workaround for QEMU failing on aarch64 asymetric multiprocessor arch + # (big/little architecture https://en.wikipedia.org/wiki/ARM_big.LITTLE) + # see https://bugs.linaro.org/show_bug.cgi?id=1443 + ncpus_bl = pmb.parse.cpuinfo.arm_big_little_first_group_ncpus() + if ncpus_bl: + ncpus = ncpus_bl + logging.info("QEMU will run on big/little architecture on the" + f" first {ncpus} cores (from /proc/cpuinfo)") + command += [rootfs_native + "/lib/ld-musl-" + + args.arch_native + ".so.1"] + command += [rootfs_native + "/usr/bin/taskset"] + command += ["-c", "0-" + str(ncpus - 1)] + + command += [rootfs_native + "/lib/ld-musl-" + + args.arch_native + ".so.1"] command += ["--library-path=" + rootfs_native + "/lib:" + rootfs_native + "/usr/lib:" + rootfs_native + "/usr/lib/pulseaudio"] @@ -115,7 +132,8 @@ def command_qemu(args, arch, img_path): command += ["-initrd", rootfs + "/boot/initramfs-" + flavor] command += ["-append", shlex.quote(cmdline)] - command += ["-smp", str(os.cpu_count())] + command += ["-smp", str(ncpus)] + command += ["-m", str(args.memory)] command += ["-serial", "stdio"]