diff mbox series

[v8,08/12] tests/vm: Added a new script for ubuntu.aarch64.

Message ID 20200529203458.1038-9-robert.foley@linaro.org
State Superseded
Headers show
Series tests/vm: Add support for aarch64 VMs | expand

Commit Message

Robert Foley May 29, 2020, 8:34 p.m. UTC
ubuntu.aarch64 provides a script to create an Ubuntu 18.04 VM.
Another new file is also added aarch64vm.py, which is a module with
common methods used by aarch64 VMs, such as how to create the
flash images.

Signed-off-by: Robert Foley <robert.foley@linaro.org>

Reviewed-by: Peter Puhov <peter.puhov@linaro.org>

---
 configure                 |  20 +++++++
 tests/vm/Makefile.include |  11 ++++
 tests/vm/aarch64vm.py     | 106 ++++++++++++++++++++++++++++++++++++++
 tests/vm/basevm.py        |  12 +++++
 tests/vm/ubuntu.aarch64   |  68 ++++++++++++++++++++++++
 5 files changed, 217 insertions(+)
 create mode 100644 tests/vm/aarch64vm.py
 create mode 100755 tests/vm/ubuntu.aarch64

-- 
2.17.1

Comments

Philippe Mathieu-Daudé May 31, 2020, 10:25 a.m. UTC | #1
Hi Robert,

On 5/29/20 10:34 PM, Robert Foley wrote:
> ubuntu.aarch64 provides a script to create an Ubuntu 18.04 VM.

> Another new file is also added aarch64vm.py, which is a module with

> common methods used by aarch64 VMs, such as how to create the

> flash images.

> 

> Signed-off-by: Robert Foley <robert.foley@linaro.org>

> Reviewed-by: Peter Puhov <peter.puhov@linaro.org>

> ---

>  configure                 |  20 +++++++

>  tests/vm/Makefile.include |  11 ++++

>  tests/vm/aarch64vm.py     | 106 ++++++++++++++++++++++++++++++++++++++

>  tests/vm/basevm.py        |  12 +++++

>  tests/vm/ubuntu.aarch64   |  68 ++++++++++++++++++++++++

>  5 files changed, 217 insertions(+)

>  create mode 100644 tests/vm/aarch64vm.py

>  create mode 100755 tests/vm/ubuntu.aarch64

> 

> diff --git a/configure b/configure

> index d82de47fdd..8a286e75a5 100755

> --- a/configure

> +++ b/configure

> @@ -411,6 +411,7 @@ prefix="/usr/local"

>  mandir="\${prefix}/share/man"

>  datadir="\${prefix}/share"

>  firmwarepath="\${prefix}/share/qemu-firmware"

> +efi_aarch64=""

>  qemu_docdir="\${prefix}/share/doc/qemu"

>  bindir="\${prefix}/bin"

>  libdir="\${prefix}/lib"

> @@ -1099,6 +1100,8 @@ for opt do

>    ;;

>    --firmwarepath=*) firmwarepath="$optarg"

>    ;;

> +  --efi-aarch64=*) efi_aarch64="$optarg"

> +  ;;

>    --host=*|--build=*|\

>    --disable-dependency-tracking|\

>    --sbindir=*|--sharedstatedir=*|\

> @@ -1753,6 +1756,7 @@ Advanced options (experts only):

>    --sysconfdir=PATH        install config in PATH$confsuffix

>    --localstatedir=PATH     install local state in PATH (set at runtime on win32)

>    --firmwarepath=PATH      search PATH for firmware files

> +  --efi-aarch64=PATH       PATH of efi file to use for aarch64 VMs.

>    --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]

>    --with-pkgversion=VERS   use specified string as sub-version of the package

>    --enable-debug           enable common debug build options

> @@ -3548,6 +3552,20 @@ EOF

>    fi

>  fi

>  

> +############################################

> +# efi-aarch64 probe

> +# Check for efi files needed by aarch64 VMs.

> +# By default we will use the efi included with QEMU.

> +# Allow user to override the path for efi also.

> +if ! test -f "$efi_aarch64"; then

> +    if test -f $source_path/pc-bios/edk2-aaarch64-code.fd.bz2; then

> +        # valid after build

> +        efi_aarch64=$PWD/pc-bios/edk2-aarch64-code.fd

> +    else

> +        efi_aarch64=""

> +    fi

> +fi

> +

>  ##########################################

>  # libcap-ng library probe

>  if test "$cap_ng" != "no" ; then

> @@ -6604,6 +6622,7 @@ if test "$docs" != "no"; then

>      echo "sphinx-build      $sphinx_build"

>  fi

>  echo "genisoimage       $genisoimage"

> +echo "efi_aarch64       $efi_aarch64"

>  echo "python_yaml       $python_yaml"

>  echo "slirp support     $slirp $(echo_version $slirp $slirp_version)"

>  if test "$slirp" != "no" ; then

> @@ -7667,6 +7686,7 @@ echo "PYTHON=$python" >> $config_host_mak

>  echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak

>  echo "SPHINX_WERROR=$sphinx_werror" >> $config_host_mak

>  echo "GENISOIMAGE=$genisoimage" >> $config_host_mak

> +echo "EFI_AARCH64=$efi_aarch64" >> $config_host_mak

>  echo "PYTHON_YAML=$python_yaml" >> $config_host_mak

>  echo "CC=$cc" >> $config_host_mak

>  if $iasl -h > /dev/null 2>&1; then

> diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include

> index f6c3892bb2..cc71e6ed0a 100644

> --- a/tests/vm/Makefile.include

> +++ b/tests/vm/Makefile.include

> @@ -5,6 +5,9 @@

>  IMAGES := freebsd netbsd openbsd centos fedora

>  ifneq ($(GENISOIMAGE),)

>  IMAGES += ubuntu.i386 centos

> +ifneq ($(EFI_AARCH64),)

> +IMAGES += ubuntu.aarch64

> +endif

>  endif

>  

>  IMAGES_DIR := $(HOME)/.cache/qemu-vm/images

> @@ -23,6 +26,11 @@ vm-help vm-test:

>  ifneq ($(GENISOIMAGE),)

>  	@echo "  vm-build-centos                 - Build QEMU in CentOS VM, with Docker"

>  	@echo "  vm-build-ubuntu.i386            - Build QEMU in ubuntu i386 VM"

> +ifneq ($(EFI_AARCH64),)

> +	@echo "  vm-build-ubuntu.aarch64         - Build QEMU in ubuntu aarch64 VM"

> +else

> +	@echo "  (install qemu-efi-aarch64 to build centos/ubuntu aarch64 images.)"


I'm not sure your test is working well, I have qemu-efi-aarch64
installed and it not automatically discovered.

# apt install qemu-efi-aarch64
qemu-efi-aarch64 is already the newest version
(0~20191122.bd85bf54-2ubuntu3).

Hint: I'm using out-of-tree builds.

> +endif

>  else

>  	@echo "  (install genisoimage to build centos/ubuntu images)"

>  endif

> @@ -65,6 +73,7 @@ $(IMAGES_DIR)/%.img:	$(SRC_PATH)/tests/vm/% \

>  		$(if $(V)$(DEBUG), --debug) \

>  		$(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \

>  		$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \

> +		$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \

>  		--image "$@" \

>  		--force \

>  		--build-image $@, \

> @@ -80,6 +89,7 @@ vm-build-%: $(IMAGES_DIR)/%.img

>  		$(if $(J),--jobs $(J)) \

>  		$(if $(V),--verbose) \

>  		$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \

> +		$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \

>  		--image "$<" \

>  		$(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \

>  		--snapshot \

> @@ -102,6 +112,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img

>  		$(if $(J),--jobs $(J)) \

>  		$(if $(V)$(DEBUG), --debug) \

>  		$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \

> +		$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \

>  		--image "$<" \

>  		--interactive \

>  		false, \

> diff --git a/tests/vm/aarch64vm.py b/tests/vm/aarch64vm.py

> new file mode 100644

> index 0000000000..bb04cb19c9

> --- /dev/null

> +++ b/tests/vm/aarch64vm.py

> @@ -0,0 +1,106 @@

> +#!/usr/bin/env python3

> +#

> +# VM testing aarch64 library

> +#

> +# Copyright 2020 Linaro

> +#

> +# Authors:

> +#  Robert Foley <robert.foley@linaro.org>

> +#

> +# This code is licensed under the GPL version 2 or later.  See

> +# the COPYING file in the top-level directory.

> +#

> +import os

> +import sys

> +import subprocess

> +import basevm

> +from qemu.accel import kvm_available

> +

> +# This is the config needed for current version of QEMU.

> +# This works for both kvm and tcg.

> +CURRENT_CONFIG = {

> +    'cpu'          : "max",

> +    'machine'      : "virt,gic-version=max",

> +}

> +

> +# The minimum minor version of QEMU we will support with aarch64 VMs is 3.

> +# QEMU versions less than 3 have various issues running these VMs.

> +QEMU_AARCH64_MIN_VERSION = 3

> +

> +# The DEFAULT_CONFIG will default to a version of

> +# parameters that works for backwards compatibility.

> +DEFAULT_CONFIG = {'kvm' : {'cpu'          : "host",

> +                           'machine'      : "virt,gic-version=host"},

> +                  'tcg' : {'cpu'          : "cortex-a57",

> +                           'machine'      : "virt"},

> +}

> +

> +def get_config_defaults(vmcls, default_config):

> +    """Fetch the configuration defaults for this VM,

> +       taking into consideration the defaults for

> +       aarch64 first, followed by the defaults for this VM."""

> +    config = default_config

> +    config.update(aarch_get_config_defaults(vmcls))

> +    return config

> +

> +def aarch_get_config_defaults(vmcls):

> +    """Set the defaults for current version of QEMU."""

> +    config = CURRENT_CONFIG

> +    args, argv = basevm.parse_args(vmcls)

> +    qemu_path = basevm.get_qemu_path(vmcls.arch, args.build_path)

> +    qemu_version = basevm.get_qemu_version(qemu_path)

> +    if qemu_version < QEMU_AARCH64_MIN_VERSION:

> +        error = "\nThis major version of QEMU {} is to old for aarch64 VMs.\n"\

> +                "The major version must be at least {}.\n"\

> +                "To continue with the current build of QEMU, "\

> +                "please restart with QEMU_LOCAL=1 .\n"

> +        print(error.format(qemu_version, QEMU_AARCH64_MIN_VERSION))

> +        exit(1)

> +    if qemu_version == QEMU_AARCH64_MIN_VERSION:

> +        # We have an older version of QEMU,

> +        # set the config values for backwards compatibility.

> +        if kvm_available('aarch64'):

> +            config.update(DEFAULT_CONFIG['kvm'])

> +        else:

> +            config.update(DEFAULT_CONFIG['tcg'])

> +    return config

> +

> +def create_flash_images(flash_dir="./", efi_img=""):

> +    """Creates the appropriate pflash files

> +       for an aarch64 VM."""

> +    flash0_path = get_flash_path(flash_dir, "flash0")

> +    flash1_path = get_flash_path(flash_dir, "flash1")

> +    fd_null = open(os.devnull, 'w')

> +    subprocess.check_call(["dd", "if=/dev/zero", "of={}".format(flash0_path),

> +                           "bs=1M", "count=64"],

> +                           stdout=fd_null, stderr=subprocess.STDOUT)

> +    # A reliable way to get the QEMU EFI image is via an installed package or

> +    # via the bios included with qemu.

> +    if not os.path.exists(efi_img):

> +        sys.stderr.write("*** efi argument is invalid ({})\n".format(efi_img))

> +        sys.stderr.write("*** please check --efi-aarch64 argument or "\

> +                         "install qemu-efi-aarch64 package\n")

> +        exit(3)

> +    subprocess.check_call(["dd", "if={}".format(efi_img),

> +                           "of={}".format(flash0_path),

> +                           "conv=notrunc"],

> +                           stdout=fd_null, stderr=subprocess.STDOUT)

> +    subprocess.check_call(["dd", "if=/dev/zero",

> +                           "of={}".format(flash1_path),

> +                           "bs=1M", "count=64"],

> +                           stdout=fd_null, stderr=subprocess.STDOUT)

> +    fd_null.close()

> +

> +def get_pflash_args(flash_dir="./"):

> +    """Returns a string that can be used to

> +       boot qemu using the appropriate pflash files

> +       for aarch64."""

> +    flash0_path = get_flash_path(flash_dir, "flash0")

> +    flash1_path = get_flash_path(flash_dir, "flash1")

> +    pflash_args_str = "-drive file={},format=raw,if=pflash "\

> +                      "-drive file={},format=raw,if=pflash"

> +    pflash_args = pflash_args_str.format(flash0_path, flash1_path)

> +    return pflash_args.split(" ")

> +

> +def get_flash_path(flash_dir, name):

> +    return os.path.join(flash_dir, "{}.img".format(name))

> diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py

> index 1aab9e3a24..f406a20466 100644

> --- a/tests/vm/basevm.py

> +++ b/tests/vm/basevm.py

> @@ -92,6 +92,7 @@ class BaseVM(object):

>          self._guest = None

>          self._genisoimage = args.genisoimage

>          self._build_path = args.build_path

> +        self._efi_aarch64 = args.efi_aarch64

>          # Allow input config to override defaults.

>          self._config = DEFAULT_CONFIG.copy()

>          if config != None:

> @@ -496,6 +497,14 @@ def get_qemu_path(arch, build_path=None):

>          qemu_path = "qemu-system-" + arch

>      return qemu_path

>  

> +def get_qemu_version(qemu_path):

> +    """Get the version number from the current QEMU,

> +       and return the major number."""

> +    output = subprocess.check_output([qemu_path, '--version'])

> +    version_line = output.decode("utf-8")

> +    version_num = re.split(' |\(', version_line)[3].split('.')[0]

> +    return int(version_num)

> +

>  def parse_config(config, args):

>      """ Parse yaml config and populate our config structure.

>          The yaml config allows the user to override the

> @@ -573,6 +582,9 @@ def parse_args(vmcls):

>      parser.add_option("--build-path", default=None,

>                        help="Path of build directory, "\

>                             "for using build tree QEMU binary. ")

> +    parser.add_option("--efi-aarch64",

> +                      default="/usr/share/qemu-efi-aarch64/QEMU_EFI.fd",

> +                      help="Path to efi image for aarch64 VMs.")

>      parser.disable_interspersed_args()

>      return parser.parse_args()

>  

> diff --git a/tests/vm/ubuntu.aarch64 b/tests/vm/ubuntu.aarch64

> new file mode 100755

> index 0000000000..6f903c029c

> --- /dev/null

> +++ b/tests/vm/ubuntu.aarch64

> @@ -0,0 +1,68 @@

> +#!/usr/bin/env python3

> +#

> +# Ubuntu aarch64 image

> +#

> +# Copyright 2020 Linaro

> +#

> +# Authors:

> +#  Robert Foley <robert.foley@linaro.org>

> +#  Originally based on ubuntu.i386 Fam Zheng <famz@redhat.com>

> +#

> +# This code is licensed under the GPL version 2 or later.  See

> +# the COPYING file in the top-level directory.

> +#

> +

> +import sys

> +import basevm

> +import aarch64vm

> +import ubuntuvm

> +

> +DEFAULT_CONFIG = {

> +    'cpu'          : "cortex-a57",

> +    'machine'      : "virt,gic-version=3",

> +    'install_cmds' : "apt-get update,"\

> +                     "apt-get build-dep -y --arch-only qemu,"\

> +                     "apt-get install -y libfdt-dev flex bison pkg-config",

> +    # We increase beyond the default time since during boot

> +    # it can take some time (many seconds) to log into the VM

> +    # especially using softmmu.

> +    'ssh_timeout'  : 60,

> +}

> +

> +class UbuntuAarch64VM(ubuntuvm.UbuntuVM):

> +    name = "ubuntu.aarch64"

> +    arch = "aarch64"

> +    image_name = "ubuntu-18.04-server-cloudimg-arm64.img"

> +    image_link = "https://cloud-images.ubuntu.com/releases/18.04/release/" + image_name

> +    image_sha256="0fdcba761965735a8a903d8b88df8e47f156f48715c00508e4315c506d7d3cb1"

> +    BUILD_SCRIPT = """

> +        set -e;

> +        cd $(mktemp -d);

> +        sudo chmod a+r /dev/vdb;

> +        tar --checkpoint=.10 -xf /dev/vdb;

> +        ./configure {configure_opts};

> +        make --output-sync {target} -j{jobs} {verbose};

> +    """

> +    def boot(self, img, extra_args=None):

> +        aarch64vm.create_flash_images(self._tmpdir, self._efi_aarch64)

> +        default_args = aarch64vm.get_pflash_args(self._tmpdir)

> +        if extra_args:

> +            extra_args.extend(default_args)

> +        else:

> +            extra_args = default_args

> +        # We always add these performance tweaks

> +        # because without them, we boot so slowly that we

> +        # can time out finding the boot efi device.

> +        if '-smp' not in extra_args and \

> +           '-smp' not in self._config['extra_args'] and \

> +           '-smp' not in self._args:

> +            # Only add if not already there to give caller option to change it.

> +            extra_args.extend(["-smp", "8"])

> +

> +        # We have overridden boot() since aarch64 has additional parameters.

> +        # Call down to the base class method.

> +        super(UbuntuAarch64VM, self).boot(img, extra_args=extra_args)

> +

> +if __name__ == "__main__":

> +    defaults = aarch64vm.get_config_defaults(UbuntuAarch64VM, DEFAULT_CONFIG)

> +    sys.exit(basevm.main(UbuntuAarch64VM, defaults))

>
Alex Bennée May 31, 2020, 10:54 a.m. UTC | #2
Philippe Mathieu-Daudé <philmd@redhat.com> writes:

> Hi Robert,

>

> On 5/29/20 10:34 PM, Robert Foley wrote:

<snip>
>> diff --git a/configure b/configure

>> index d82de47fdd..8a286e75a5 100755

>> --- a/configure

>> +++ b/configure

>> @@ -411,6 +411,7 @@ prefix="/usr/local"

>>  mandir="\${prefix}/share/man"

>>  datadir="\${prefix}/share"

>>  firmwarepath="\${prefix}/share/qemu-firmware"

>> +efi_aarch64=""

>>  qemu_docdir="\${prefix}/share/doc/qemu"

>>  bindir="\${prefix}/bin"

>>  libdir="\${prefix}/lib"

>> @@ -1099,6 +1100,8 @@ for opt do

>>    ;;

>>    --firmwarepath=*) firmwarepath="$optarg"

>>    ;;

>> +  --efi-aarch64=*) efi_aarch64="$optarg"

>> +  ;;

>>    --host=*|--build=*|\

>>    --disable-dependency-tracking|\

>>    --sbindir=*|--sharedstatedir=*|\

>> @@ -1753,6 +1756,7 @@ Advanced options (experts only):

>>    --sysconfdir=PATH        install config in PATH$confsuffix

>>    --localstatedir=PATH     install local state in PATH (set at runtime on win32)

>>    --firmwarepath=PATH      search PATH for firmware files

>> +  --efi-aarch64=PATH       PATH of efi file to use for aarch64 VMs.

>>    --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]

>>    --with-pkgversion=VERS   use specified string as sub-version of the package

>>    --enable-debug           enable common debug build options

>> @@ -3548,6 +3552,20 @@ EOF

>>    fi

>>  fi

>>  

>> +############################################

>> +# efi-aarch64 probe

>> +# Check for efi files needed by aarch64 VMs.

>> +# By default we will use the efi included with QEMU.

>> +# Allow user to override the path for efi also.

>> +if ! test -f "$efi_aarch64"; then

>> +    if test -f $source_path/pc-bios/edk2-aaarch64-code.fd.bz2; then

>> +        # valid after build

>> +        efi_aarch64=$PWD/pc-bios/edk2-aarch64-code.fd

>> +    else

>> +        efi_aarch64=""

>> +    fi

>> +fi

>> +

<snip>
>>  

>>  IMAGES_DIR := $(HOME)/.cache/qemu-vm/images

>> @@ -23,6 +26,11 @@ vm-help vm-test:

>>  ifneq ($(GENISOIMAGE),)

>>  	@echo "  vm-build-centos                 - Build QEMU in CentOS VM, with Docker"

>>  	@echo "  vm-build-ubuntu.i386            - Build QEMU in ubuntu i386 VM"

>> +ifneq ($(EFI_AARCH64),)

>> +	@echo "  vm-build-ubuntu.aarch64         - Build QEMU in ubuntu aarch64 VM"

>> +else

>> +	@echo "  (install qemu-efi-aarch64 to build centos/ubuntu aarch64 images.)"

>

> I'm not sure your test is working well, I have qemu-efi-aarch64

> installed and it not automatically discovered.

>

> # apt install qemu-efi-aarch64

> qemu-efi-aarch64 is already the newest version

> (0~20191122.bd85bf54-2ubuntu3).

>

> Hint: I'm using out-of-tree builds.


I think efi_aarch64="" needs to be the default path, which can then be
overridden by the command line or finally fall back to the built in
image.

-- 
Alex Bennée
Robert Foley June 1, 2020, 1:11 p.m. UTC | #3
On Sun, 31 May 2020 at 06:54, Alex Bennée <alex.bennee@linaro.org> wrote:
>

>

> Philippe Mathieu-Daudé <philmd@redhat.com> writes:

>

> > Hi Robert,

> >

> > On 5/29/20 10:34 PM, Robert Foley wrote:

> <snip>

> >> diff --git a/configure b/configure

> >> index d82de47fdd..8a286e75a5 100755

> >> --- a/configure

> >> +++ b/configure

> >> @@ -411,6 +411,7 @@ prefix="/usr/local"

> >>  mandir="\${prefix}/share/man"

> >>  datadir="\${prefix}/share"

> >>  firmwarepath="\${prefix}/share/qemu-firmware"

> >> +efi_aarch64=""

> >>  qemu_docdir="\${prefix}/share/doc/qemu"

> >>  bindir="\${prefix}/bin"

> >>  libdir="\${prefix}/lib"

> >> @@ -1099,6 +1100,8 @@ for opt do

> >>    ;;

> >>    --firmwarepath=*) firmwarepath="$optarg"

> >>    ;;

> >> +  --efi-aarch64=*) efi_aarch64="$optarg"

> >> +  ;;

> >>    --host=*|--build=*|\

> >>    --disable-dependency-tracking|\

> >>    --sbindir=*|--sharedstatedir=*|\

> >> @@ -1753,6 +1756,7 @@ Advanced options (experts only):

> >>    --sysconfdir=PATH        install config in PATH$confsuffix

> >>    --localstatedir=PATH     install local state in PATH (set at runtime on win32)

> >>    --firmwarepath=PATH      search PATH for firmware files

> >> +  --efi-aarch64=PATH       PATH of efi file to use for aarch64 VMs.

> >>    --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]

> >>    --with-pkgversion=VERS   use specified string as sub-version of the package

> >>    --enable-debug           enable common debug build options

> >> @@ -3548,6 +3552,20 @@ EOF

> >>    fi

> >>  fi

> >>

> >> +############################################

> >> +# efi-aarch64 probe

> >> +# Check for efi files needed by aarch64 VMs.

> >> +# By default we will use the efi included with QEMU.

> >> +# Allow user to override the path for efi also.

> >> +if ! test -f "$efi_aarch64"; then

> >> +    if test -f $source_path/pc-bios/edk2-aaarch64-code.fd.bz2; then

> >> +        # valid after build

> >> +        efi_aarch64=$PWD/pc-bios/edk2-aarch64-code.fd

> >> +    else

> >> +        efi_aarch64=""

> >> +    fi

> >> +fi

> >> +

> <snip>

> >>

> >>  IMAGES_DIR := $(HOME)/.cache/qemu-vm/images

> >> @@ -23,6 +26,11 @@ vm-help vm-test:

> >>  ifneq ($(GENISOIMAGE),)

> >>      @echo "  vm-build-centos                 - Build QEMU in CentOS VM, with Docker"

> >>      @echo "  vm-build-ubuntu.i386            - Build QEMU in ubuntu i386 VM"

> >> +ifneq ($(EFI_AARCH64),)

> >> +    @echo "  vm-build-ubuntu.aarch64         - Build QEMU in ubuntu aarch64 VM"

> >> +else

> >> +    @echo "  (install qemu-efi-aarch64 to build centos/ubuntu aarch64 images.)"

> >

> > I'm not sure your test is working well, I have qemu-efi-aarch64

> > installed and it not automatically discovered.

> >

> > # apt install qemu-efi-aarch64

> > qemu-efi-aarch64 is already the newest version

> > (0~20191122.bd85bf54-2ubuntu3).

> >

> > Hint: I'm using out-of-tree builds.

>

> I think efi_aarch64="" needs to be the default path, which can then be

> overridden by the command line or finally fall back to the built in

> image.


I think what we are saying here is that if we want to use the qemu-efi-aarch64
package's image we should override it on the command line via --efi-aarch64.

Seems like the text above needs adjustment to something like:
> +ifneq ($(EFI_AARCH64),)

> +    @echo "  vm-build-ubuntu.aarch64         - Build QEMU in ubuntu aarch64 VM"

> +else

       @echo "  to build centos/ubuntu aarch64 images use configure
--efi-aarch64"

Thanks & Regards,
-Rob
>

> --

> Alex Bennée
diff mbox series

Patch

diff --git a/configure b/configure
index d82de47fdd..8a286e75a5 100755
--- a/configure
+++ b/configure
@@ -411,6 +411,7 @@  prefix="/usr/local"
 mandir="\${prefix}/share/man"
 datadir="\${prefix}/share"
 firmwarepath="\${prefix}/share/qemu-firmware"
+efi_aarch64=""
 qemu_docdir="\${prefix}/share/doc/qemu"
 bindir="\${prefix}/bin"
 libdir="\${prefix}/lib"
@@ -1099,6 +1100,8 @@  for opt do
   ;;
   --firmwarepath=*) firmwarepath="$optarg"
   ;;
+  --efi-aarch64=*) efi_aarch64="$optarg"
+  ;;
   --host=*|--build=*|\
   --disable-dependency-tracking|\
   --sbindir=*|--sharedstatedir=*|\
@@ -1753,6 +1756,7 @@  Advanced options (experts only):
   --sysconfdir=PATH        install config in PATH$confsuffix
   --localstatedir=PATH     install local state in PATH (set at runtime on win32)
   --firmwarepath=PATH      search PATH for firmware files
+  --efi-aarch64=PATH       PATH of efi file to use for aarch64 VMs.
   --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
   --with-pkgversion=VERS   use specified string as sub-version of the package
   --enable-debug           enable common debug build options
@@ -3548,6 +3552,20 @@  EOF
   fi
 fi
 
+############################################
+# efi-aarch64 probe
+# Check for efi files needed by aarch64 VMs.
+# By default we will use the efi included with QEMU.
+# Allow user to override the path for efi also.
+if ! test -f "$efi_aarch64"; then
+    if test -f $source_path/pc-bios/edk2-aaarch64-code.fd.bz2; then
+        # valid after build
+        efi_aarch64=$PWD/pc-bios/edk2-aarch64-code.fd
+    else
+        efi_aarch64=""
+    fi
+fi
+
 ##########################################
 # libcap-ng library probe
 if test "$cap_ng" != "no" ; then
@@ -6604,6 +6622,7 @@  if test "$docs" != "no"; then
     echo "sphinx-build      $sphinx_build"
 fi
 echo "genisoimage       $genisoimage"
+echo "efi_aarch64       $efi_aarch64"
 echo "python_yaml       $python_yaml"
 echo "slirp support     $slirp $(echo_version $slirp $slirp_version)"
 if test "$slirp" != "no" ; then
@@ -7667,6 +7686,7 @@  echo "PYTHON=$python" >> $config_host_mak
 echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak
 echo "SPHINX_WERROR=$sphinx_werror" >> $config_host_mak
 echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
+echo "EFI_AARCH64=$efi_aarch64" >> $config_host_mak
 echo "PYTHON_YAML=$python_yaml" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 if $iasl -h > /dev/null 2>&1; then
diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include
index f6c3892bb2..cc71e6ed0a 100644
--- a/tests/vm/Makefile.include
+++ b/tests/vm/Makefile.include
@@ -5,6 +5,9 @@ 
 IMAGES := freebsd netbsd openbsd centos fedora
 ifneq ($(GENISOIMAGE),)
 IMAGES += ubuntu.i386 centos
+ifneq ($(EFI_AARCH64),)
+IMAGES += ubuntu.aarch64
+endif
 endif
 
 IMAGES_DIR := $(HOME)/.cache/qemu-vm/images
@@ -23,6 +26,11 @@  vm-help vm-test:
 ifneq ($(GENISOIMAGE),)
 	@echo "  vm-build-centos                 - Build QEMU in CentOS VM, with Docker"
 	@echo "  vm-build-ubuntu.i386            - Build QEMU in ubuntu i386 VM"
+ifneq ($(EFI_AARCH64),)
+	@echo "  vm-build-ubuntu.aarch64         - Build QEMU in ubuntu aarch64 VM"
+else
+	@echo "  (install qemu-efi-aarch64 to build centos/ubuntu aarch64 images.)"
+endif
 else
 	@echo "  (install genisoimage to build centos/ubuntu images)"
 endif
@@ -65,6 +73,7 @@  $(IMAGES_DIR)/%.img:	$(SRC_PATH)/tests/vm/% \
 		$(if $(V)$(DEBUG), --debug) \
 		$(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \
 		$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
+		$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
 		--image "$@" \
 		--force \
 		--build-image $@, \
@@ -80,6 +89,7 @@  vm-build-%: $(IMAGES_DIR)/%.img
 		$(if $(J),--jobs $(J)) \
 		$(if $(V),--verbose) \
 		$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
+		$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
 		--image "$<" \
 		$(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \
 		--snapshot \
@@ -102,6 +112,7 @@  vm-boot-ssh-%: $(IMAGES_DIR)/%.img
 		$(if $(J),--jobs $(J)) \
 		$(if $(V)$(DEBUG), --debug) \
 		$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
+		$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
 		--image "$<" \
 		--interactive \
 		false, \
diff --git a/tests/vm/aarch64vm.py b/tests/vm/aarch64vm.py
new file mode 100644
index 0000000000..bb04cb19c9
--- /dev/null
+++ b/tests/vm/aarch64vm.py
@@ -0,0 +1,106 @@ 
+#!/usr/bin/env python3
+#
+# VM testing aarch64 library
+#
+# Copyright 2020 Linaro
+#
+# Authors:
+#  Robert Foley <robert.foley@linaro.org>
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+#
+import os
+import sys
+import subprocess
+import basevm
+from qemu.accel import kvm_available
+
+# This is the config needed for current version of QEMU.
+# This works for both kvm and tcg.
+CURRENT_CONFIG = {
+    'cpu'          : "max",
+    'machine'      : "virt,gic-version=max",
+}
+
+# The minimum minor version of QEMU we will support with aarch64 VMs is 3.
+# QEMU versions less than 3 have various issues running these VMs.
+QEMU_AARCH64_MIN_VERSION = 3
+
+# The DEFAULT_CONFIG will default to a version of
+# parameters that works for backwards compatibility.
+DEFAULT_CONFIG = {'kvm' : {'cpu'          : "host",
+                           'machine'      : "virt,gic-version=host"},
+                  'tcg' : {'cpu'          : "cortex-a57",
+                           'machine'      : "virt"},
+}
+
+def get_config_defaults(vmcls, default_config):
+    """Fetch the configuration defaults for this VM,
+       taking into consideration the defaults for
+       aarch64 first, followed by the defaults for this VM."""
+    config = default_config
+    config.update(aarch_get_config_defaults(vmcls))
+    return config
+
+def aarch_get_config_defaults(vmcls):
+    """Set the defaults for current version of QEMU."""
+    config = CURRENT_CONFIG
+    args, argv = basevm.parse_args(vmcls)
+    qemu_path = basevm.get_qemu_path(vmcls.arch, args.build_path)
+    qemu_version = basevm.get_qemu_version(qemu_path)
+    if qemu_version < QEMU_AARCH64_MIN_VERSION:
+        error = "\nThis major version of QEMU {} is to old for aarch64 VMs.\n"\
+                "The major version must be at least {}.\n"\
+                "To continue with the current build of QEMU, "\
+                "please restart with QEMU_LOCAL=1 .\n"
+        print(error.format(qemu_version, QEMU_AARCH64_MIN_VERSION))
+        exit(1)
+    if qemu_version == QEMU_AARCH64_MIN_VERSION:
+        # We have an older version of QEMU,
+        # set the config values for backwards compatibility.
+        if kvm_available('aarch64'):
+            config.update(DEFAULT_CONFIG['kvm'])
+        else:
+            config.update(DEFAULT_CONFIG['tcg'])
+    return config
+
+def create_flash_images(flash_dir="./", efi_img=""):
+    """Creates the appropriate pflash files
+       for an aarch64 VM."""
+    flash0_path = get_flash_path(flash_dir, "flash0")
+    flash1_path = get_flash_path(flash_dir, "flash1")
+    fd_null = open(os.devnull, 'w')
+    subprocess.check_call(["dd", "if=/dev/zero", "of={}".format(flash0_path),
+                           "bs=1M", "count=64"],
+                           stdout=fd_null, stderr=subprocess.STDOUT)
+    # A reliable way to get the QEMU EFI image is via an installed package or
+    # via the bios included with qemu.
+    if not os.path.exists(efi_img):
+        sys.stderr.write("*** efi argument is invalid ({})\n".format(efi_img))
+        sys.stderr.write("*** please check --efi-aarch64 argument or "\
+                         "install qemu-efi-aarch64 package\n")
+        exit(3)
+    subprocess.check_call(["dd", "if={}".format(efi_img),
+                           "of={}".format(flash0_path),
+                           "conv=notrunc"],
+                           stdout=fd_null, stderr=subprocess.STDOUT)
+    subprocess.check_call(["dd", "if=/dev/zero",
+                           "of={}".format(flash1_path),
+                           "bs=1M", "count=64"],
+                           stdout=fd_null, stderr=subprocess.STDOUT)
+    fd_null.close()
+
+def get_pflash_args(flash_dir="./"):
+    """Returns a string that can be used to
+       boot qemu using the appropriate pflash files
+       for aarch64."""
+    flash0_path = get_flash_path(flash_dir, "flash0")
+    flash1_path = get_flash_path(flash_dir, "flash1")
+    pflash_args_str = "-drive file={},format=raw,if=pflash "\
+                      "-drive file={},format=raw,if=pflash"
+    pflash_args = pflash_args_str.format(flash0_path, flash1_path)
+    return pflash_args.split(" ")
+
+def get_flash_path(flash_dir, name):
+    return os.path.join(flash_dir, "{}.img".format(name))
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 1aab9e3a24..f406a20466 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -92,6 +92,7 @@  class BaseVM(object):
         self._guest = None
         self._genisoimage = args.genisoimage
         self._build_path = args.build_path
+        self._efi_aarch64 = args.efi_aarch64
         # Allow input config to override defaults.
         self._config = DEFAULT_CONFIG.copy()
         if config != None:
@@ -496,6 +497,14 @@  def get_qemu_path(arch, build_path=None):
         qemu_path = "qemu-system-" + arch
     return qemu_path
 
+def get_qemu_version(qemu_path):
+    """Get the version number from the current QEMU,
+       and return the major number."""
+    output = subprocess.check_output([qemu_path, '--version'])
+    version_line = output.decode("utf-8")
+    version_num = re.split(' |\(', version_line)[3].split('.')[0]
+    return int(version_num)
+
 def parse_config(config, args):
     """ Parse yaml config and populate our config structure.
         The yaml config allows the user to override the
@@ -573,6 +582,9 @@  def parse_args(vmcls):
     parser.add_option("--build-path", default=None,
                       help="Path of build directory, "\
                            "for using build tree QEMU binary. ")
+    parser.add_option("--efi-aarch64",
+                      default="/usr/share/qemu-efi-aarch64/QEMU_EFI.fd",
+                      help="Path to efi image for aarch64 VMs.")
     parser.disable_interspersed_args()
     return parser.parse_args()
 
diff --git a/tests/vm/ubuntu.aarch64 b/tests/vm/ubuntu.aarch64
new file mode 100755
index 0000000000..6f903c029c
--- /dev/null
+++ b/tests/vm/ubuntu.aarch64
@@ -0,0 +1,68 @@ 
+#!/usr/bin/env python3
+#
+# Ubuntu aarch64 image
+#
+# Copyright 2020 Linaro
+#
+# Authors:
+#  Robert Foley <robert.foley@linaro.org>
+#  Originally based on ubuntu.i386 Fam Zheng <famz@redhat.com>
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+#
+
+import sys
+import basevm
+import aarch64vm
+import ubuntuvm
+
+DEFAULT_CONFIG = {
+    'cpu'          : "cortex-a57",
+    'machine'      : "virt,gic-version=3",
+    'install_cmds' : "apt-get update,"\
+                     "apt-get build-dep -y --arch-only qemu,"\
+                     "apt-get install -y libfdt-dev flex bison pkg-config",
+    # We increase beyond the default time since during boot
+    # it can take some time (many seconds) to log into the VM
+    # especially using softmmu.
+    'ssh_timeout'  : 60,
+}
+
+class UbuntuAarch64VM(ubuntuvm.UbuntuVM):
+    name = "ubuntu.aarch64"
+    arch = "aarch64"
+    image_name = "ubuntu-18.04-server-cloudimg-arm64.img"
+    image_link = "https://cloud-images.ubuntu.com/releases/18.04/release/" + image_name
+    image_sha256="0fdcba761965735a8a903d8b88df8e47f156f48715c00508e4315c506d7d3cb1"
+    BUILD_SCRIPT = """
+        set -e;
+        cd $(mktemp -d);
+        sudo chmod a+r /dev/vdb;
+        tar --checkpoint=.10 -xf /dev/vdb;
+        ./configure {configure_opts};
+        make --output-sync {target} -j{jobs} {verbose};
+    """
+    def boot(self, img, extra_args=None):
+        aarch64vm.create_flash_images(self._tmpdir, self._efi_aarch64)
+        default_args = aarch64vm.get_pflash_args(self._tmpdir)
+        if extra_args:
+            extra_args.extend(default_args)
+        else:
+            extra_args = default_args
+        # We always add these performance tweaks
+        # because without them, we boot so slowly that we
+        # can time out finding the boot efi device.
+        if '-smp' not in extra_args and \
+           '-smp' not in self._config['extra_args'] and \
+           '-smp' not in self._args:
+            # Only add if not already there to give caller option to change it.
+            extra_args.extend(["-smp", "8"])
+
+        # We have overridden boot() since aarch64 has additional parameters.
+        # Call down to the base class method.
+        super(UbuntuAarch64VM, self).boot(img, extra_args=extra_args)
+
+if __name__ == "__main__":
+    defaults = aarch64vm.get_config_defaults(UbuntuAarch64VM, DEFAULT_CONFIG)
+    sys.exit(basevm.main(UbuntuAarch64VM, defaults))