Final test and misc fixes:

- add basic coverage analysis script
   - gdbstub only build one of libgdb_user/softmmu
   - don't break BSD gdb by advertising AUXV feature
   - add MAINTAINERS section for policy docs
   - update hexagon toolchain
   - explicitly invoke iotests with python for BSDs benefit
   - use system python on NetBSD
   - add some tests for the new KVM Xen guest support
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmQsOscACgkQ+9DbCVqe
 KkSm6Af/X+vvzdlmXgGt3uw2odqV6KMfXEkds5lHZIIqQhsLvV0mrkTcIKTswWhL
 JRC7jiPmn5hfwvgDy5WfcczGzELSqfBgqHsm9zqVcboTGgJfr2eMtoUlMCQi6lFR
 InomhTb+VzPxuUx82oryufm7bsopG8C+HVr3ZtHNFI3usIrLlscZstkiYMueGUCb
 PJ60mykfd7hegaTgwKNbUXqZ+Oy/u4W7UPWBkrR7xJzW623t7S5EWV2ZNbdJgKO6
 utY3VGikir/OcnNKy7NuXp2t3K+5KALFZW3Jbav8hVLy5biMGYUF8886B0FL2m+n
 E44J67crEYNJMamtzYJ+FdkGEMrS5Q==
 =yCka
 -----END PGP SIGNATURE-----

Merge tag 'pull-for-8.0-040423-2' of https://gitlab.com/stsquad/qemu into staging

Final test and misc fixes:

  - add basic coverage analysis script
  - gdbstub only build one of libgdb_user/softmmu
  - don't break BSD gdb by advertising AUXV feature
  - add MAINTAINERS section for policy docs
  - update hexagon toolchain
  - explicitly invoke iotests with python for BSDs benefit
  - use system python on NetBSD
  - add some tests for the new KVM Xen guest support

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmQsOscACgkQ+9DbCVqe
# KkSm6Af/X+vvzdlmXgGt3uw2odqV6KMfXEkds5lHZIIqQhsLvV0mrkTcIKTswWhL
# JRC7jiPmn5hfwvgDy5WfcczGzELSqfBgqHsm9zqVcboTGgJfr2eMtoUlMCQi6lFR
# InomhTb+VzPxuUx82oryufm7bsopG8C+HVr3ZtHNFI3usIrLlscZstkiYMueGUCb
# PJ60mykfd7hegaTgwKNbUXqZ+Oy/u4W7UPWBkrR7xJzW623t7S5EWV2ZNbdJgKO6
# utY3VGikir/OcnNKy7NuXp2t3K+5KALFZW3Jbav8hVLy5biMGYUF8886B0FL2m+n
# E44J67crEYNJMamtzYJ+FdkGEMrS5Q==
# =yCka
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 04 Apr 2023 15:57:11 BST
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* tag 'pull-for-8.0-040423-2' of https://gitlab.com/stsquad/qemu:
  tests/avocado: Test Xen guest support under KVM
  gitlab: fix typo
  tests/vm: use the default system python for NetBSD
  tests/qemu-iotests: explicitly invoke 'check' via 'python'
  Use hexagon toolchain version 16.0.0
  metadata: add .git-blame-ignore-revs
  MAINTAINERS: add a section for policy documents
  gdbstub: don't report auxv feature unless on Linux
  gdbstub: Only build libgdb_user.fa / libgdb_softmmu.fa if necessary
  scripts/coverage: initial coverage comparison script

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2023-04-04 17:02:01 +01:00
commit 8a712df4d4
10 changed files with 342 additions and 10 deletions

21
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,21 @@
#
# List of code-formatting clean ups the git blame can ignore
#
# git blame --ignore-revs-file .git-blame-ignore-revs
#
# or
#
# git config blame.ignoreRevsFile .git-blame-ignore-revs
#
# gdbstub: clean-up indents
ad9e4585b3c7425759d3eea697afbca71d2c2082
# e1000e: fix code style
0eadd56bf53ab196a16d492d7dd31c62e1c24c32
# target/riscv: coding style fixes
8c7feddddd9218b407792120bcfda0347ed16205
# replace TABs with spaces
48805df9c22a0700fba4b3b548fafaa21726ca68

View File

@ -75,5 +75,5 @@
- if: '$QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != "qemu-project"'
when: manual
# Jobs can run if any jobs they depend on were successfull
# Jobs can run if any jobs they depend on were successful
- when: on_success

View File

@ -64,6 +64,20 @@ L: qemu-devel@nongnu.org
F: *
F: */
Project policy and developer guides
R: Alex Bennée <alex.bennee@linaro.org>
R: Daniel P. Berrangé <berrange@redhat.com>
R: Thomas Huth <thuth@redhat.com>
R: Markus Armbruster <armbru@redhat.com>
R: Philippe Mathieu-Daudé <philmd@linaro.org>
W: https://www.qemu.org/docs/master/devel/index.html
S: Odd Fixes
F: docs/devel/style.rst
F: docs/devel/code-of-conduct.rst
F: docs/devel/conflict-resolution.rst
F: docs/devel/submitting-a-patch.rst
F: docs/devel/submitting-a-pull-request.rst
Responsible Disclosure, Reporting Security Issues
-------------------------------------------------
W: https://wiki.qemu.org/SecurityProcess
@ -3906,3 +3920,8 @@ Performance Tools and Tests
M: Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
S: Maintained
F: scripts/performance/
Code Coverage Tools
M: Alex Bennée <alex.bennee@linaro.org>
S: Odd Fixes
F: scripts/coverage/

View File

@ -1468,7 +1468,7 @@ static void handle_query_supported(GArray *params, void *user_ctx)
";ReverseStep+;ReverseContinue+");
}
#ifdef CONFIG_USER_ONLY
#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX)
if (gdbserver_state.c_cpu->opaque) {
g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
}

View File

@ -20,11 +20,13 @@ gdb_softmmu_ss = gdb_softmmu_ss.apply(config_host, strict: false)
libgdb_user = static_library('gdb_user',
gdb_user_ss.sources() + genh,
name_suffix: 'fa',
c_args: '-DCONFIG_USER_ONLY')
c_args: '-DCONFIG_USER_ONLY',
build_by_default: have_user)
libgdb_softmmu = static_library('gdb_softmmu',
gdb_softmmu_ss.sources() + genh,
name_suffix: 'fa')
name_suffix: 'fa',
build_by_default: have_system)
gdb_user = declare_dependency(link_whole: libgdb_user)
user_ss.add(gdb_user)

View File

@ -0,0 +1,119 @@
#!/usr/bin/env python3
#
# Compare output of two gcovr JSON reports and report differences. To
# generate the required output first:
# - create two build dirs with --enable-gcov
# - run set of tests in each
# - run make coverage-html in each
# - run gcovr --json --exclude-unreachable-branches \
# --print-summary -o coverage.json --root ../../ . *.p
#
# Author: Alex Bennée <alex.bennee@linaro.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
import argparse
import json
import sys
from pathlib import Path
def create_parser():
parser = argparse.ArgumentParser(
prog='compare_gcov_json',
description='analyse the differences in coverage between two runs')
parser.add_argument('-a', type=Path, default=None,
help=('First file to check'))
parser.add_argument('-b', type=Path, default=None,
help=('Second file to check'))
parser.add_argument('--verbose', action='store_true', default=False,
help=('A minimal verbosity level that prints the '
'overall result of the check/wait'))
return parser
# See https://gcovr.com/en/stable/output/json.html#json-format-reference
def load_json(json_file_path: Path, verbose = False) -> dict[str, set[int]]:
with open(json_file_path) as f:
data = json.load(f)
root_dir = json_file_path.absolute().parent
covered_lines = dict()
for filecov in data["files"]:
file_path = Path(filecov["file"])
# account for generated files - map into src tree
resolved_path = Path(file_path).absolute()
if resolved_path.is_relative_to(root_dir):
file_path = resolved_path.relative_to(root_dir)
# print(f"remapped {resolved_path} to {file_path}")
lines = filecov["lines"]
executed_lines = set(
linecov["line_number"]
for linecov in filecov["lines"]
if linecov["count"] != 0 and not linecov["gcovr/noncode"]
)
# if this file has any coverage add it to the system
if len(executed_lines) > 0:
if verbose:
print(f"file {file_path} {len(executed_lines)}/{len(lines)}")
covered_lines[str(file_path)] = executed_lines
return covered_lines
def find_missing_files(first, second):
"""
Return a list of files not covered in the second set
"""
missing_files = []
for f in sorted(first):
file_a = first[f]
try:
file_b = second[f]
except KeyError:
missing_files.append(f)
return missing_files
def main():
"""
Script entry point
"""
parser = create_parser()
args = parser.parse_args()
if not args.a or not args.b:
print("We need two files to compare")
sys.exit(1)
first_coverage = load_json(args.a, args.verbose)
second_coverage = load_json(args.b, args.verbose)
first_missing = find_missing_files(first_coverage,
second_coverage)
second_missing = find_missing_files(second_coverage,
first_coverage)
a_name = args.a.parent.name
b_name = args.b.parent.name
print(f"{b_name} missing coverage in {len(first_missing)} files")
for f in first_missing:
print(f" {f}")
print(f"{a_name} missing coverage in {len(second_missing)} files")
for f in second_missing:
print(f" {f}")
if __name__ == '__main__':
main()

View File

@ -0,0 +1,171 @@
# KVM Xen guest functional tests
#
# Copyright © 2021 Red Hat, Inc.
# Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Author:
# David Woodhouse <dwmw2@infradead.org>
# Alex Bennée <alex.bennee@linaro.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later
import os
from qemu.machine import machine
from avocado_qemu import LinuxSSHMixIn
from avocado_qemu import QemuSystemTest
from avocado_qemu import wait_for_console_pattern
class KVMXenGuest(QemuSystemTest, LinuxSSHMixIn):
"""
:avocado: tags=arch:x86_64
:avocado: tags=machine:q35
:avocado: tags=accel:kvm
:avocado: tags=kvm_xen_guest
"""
KERNEL_DEFAULT = 'printk.time=0 root=/dev/xvda console=ttyS0'
kernel_path = None
kernel_params = None
# Fetch assets from the kvm-xen-guest subdir of my shared test
# images directory on fileserver.linaro.org where you can find
# build instructions for how they where assembled.
def get_asset(self, name, sha1):
base_url = ('https://fileserver.linaro.org/s/'
'kE4nCFLdQcoBF9t/download?'
'path=%2Fkvm-xen-guest&files=' )
url = base_url + name
# use explicit name rather than failing to neatly parse the
# URL into a unique one
return self.fetch_asset(name=name, locations=(url), asset_hash=sha1)
def common_vm_setup(self):
# We also catch lack of KVM_XEN support if we fail to launch
self.require_accelerator("kvm")
self.vm.set_console()
self.vm.add_args("-accel", "kvm,xen-version=0x4000a,kernel-irqchip=split")
self.vm.add_args("-smp", "2")
self.kernel_path = self.get_asset("bzImage",
"367962983d0d32109998a70b45dcee4672d0b045")
self.rootfs = self.get_asset("rootfs.ext4",
"f1478401ea4b3fa2ea196396be44315bab2bb5e4")
def run_and_check(self):
self.vm.add_args('-kernel', self.kernel_path,
'-append', self.kernel_params,
'-drive', f"file={self.rootfs},if=none,format=raw,id=drv0",
'-device', 'xen-disk,drive=drv0,vdev=xvda',
'-device', 'virtio-net-pci,netdev=unet',
'-netdev', 'user,id=unet,hostfwd=:127.0.0.1:0-:22')
try:
self.vm.launch()
except machine.VMLaunchFailure as e:
if "Xen HVM guest support not present" in e.output:
self.cancel("KVM Xen support is not present "
"(need v5.12+ kernel with CONFIG_KVM_XEN)")
elif "Property 'kvm-accel.xen-version' not found" in e.output:
self.cancel("QEMU not built with CONFIG_XEN_EMU support")
else:
raise e
self.log.info('VM launched, waiting for sshd')
console_pattern = 'Starting dropbear sshd: OK'
wait_for_console_pattern(self, console_pattern, 'Oops')
self.log.info('sshd ready')
self.ssh_connect('root', '', False)
self.ssh_command('cat /proc/cmdline')
self.ssh_command('dmesg | grep -e "Grant table initialized"')
def test_kvm_xen_guest(self):
"""
:avocado: tags=kvm_xen_guest
"""
self.common_vm_setup()
self.kernel_params = (self.KERNEL_DEFAULT +
' xen_emul_unplug=ide-disks')
self.run_and_check()
self.ssh_command('grep xen-pirq.*msi /proc/interrupts')
def test_kvm_xen_guest_nomsi(self):
"""
:avocado: tags=kvm_xen_guest_nomsi
"""
self.common_vm_setup()
self.kernel_params = (self.KERNEL_DEFAULT +
' xen_emul_unplug=ide-disks pci=nomsi')
self.run_and_check()
self.ssh_command('grep xen-pirq.* /proc/interrupts')
def test_kvm_xen_guest_noapic_nomsi(self):
"""
:avocado: tags=kvm_xen_guest_noapic_nomsi
"""
self.common_vm_setup()
self.kernel_params = (self.KERNEL_DEFAULT +
' xen_emul_unplug=ide-disks noapic pci=nomsi')
self.run_and_check()
self.ssh_command('grep xen-pirq /proc/interrupts')
def test_kvm_xen_guest_vapic(self):
"""
:avocado: tags=kvm_xen_guest_vapic
"""
self.common_vm_setup()
self.vm.add_args('-cpu', 'host,+xen-vapic')
self.kernel_params = (self.KERNEL_DEFAULT +
' xen_emul_unplug=ide-disks')
self.run_and_check()
self.ssh_command('grep xen-pirq /proc/interrupts')
self.ssh_command('grep PCI-MSI /proc/interrupts')
def test_kvm_xen_guest_novector(self):
"""
:avocado: tags=kvm_xen_guest_novector
"""
self.common_vm_setup()
self.kernel_params = (self.KERNEL_DEFAULT +
' xen_emul_unplug=ide-disks' +
' xen_no_vector_callback')
self.run_and_check()
self.ssh_command('grep xen-platform-pci /proc/interrupts')
def test_kvm_xen_guest_novector_nomsi(self):
"""
:avocado: tags=kvm_xen_guest_novector_nomsi
"""
self.common_vm_setup()
self.kernel_params = (self.KERNEL_DEFAULT +
' xen_emul_unplug=ide-disks pci=nomsi' +
' xen_no_vector_callback')
self.run_and_check()
self.ssh_command('grep xen-platform-pci /proc/interrupts')
def test_kvm_xen_guest_novector_noapic(self):
"""
:avocado: tags=kvm_xen_guest_novector_noapic
"""
self.common_vm_setup()
self.kernel_params = (self.KERNEL_DEFAULT +
' xen_emul_unplug=ide-disks' +
' xen_no_vector_callback noapic')
self.run_and_check()
self.ssh_command('grep xen-platform-pci /proc/interrupts')

View File

@ -27,7 +27,7 @@ RUN apt-get update && \
ENV TOOLCHAIN_INSTALL /opt
ENV TOOLCHAIN_RELEASE 15.0.3
ENV TOOLCHAIN_RELEASE 16.0.0
ENV TOOLCHAIN_BASENAME "clang+llvm-${TOOLCHAIN_RELEASE}-cross-hexagon-unknown-linux-musl"
ENV TOOLCHAIN_URL https://codelinaro.jfrog.io/artifactory/codelinaro-toolchain-for-hexagon/v${TOOLCHAIN_RELEASE}/${TOOLCHAIN_BASENAME}.tar.xz

View File

@ -47,19 +47,20 @@ foreach format, speed: qemu_iotests_formats
endif
rc = run_command(
[qemu_iotests_check_cmd] + args + ['-n'],
[python, qemu_iotests_check_cmd] + args + ['-n'],
check: true,
)
foreach item: rc.stdout().strip().split()
args = ['-tap', '-' + format, item,
args = [qemu_iotests_check_cmd,
'-tap', '-' + format, item,
'--source-dir', meson.current_source_dir(),
'--build-dir', meson.current_build_dir()]
# Some individual tests take as long as 45 seconds
# Bump the timeout to 3 minutes for some headroom
# on slow machines to minimize spurious failures
test('io-' + format + '-' + item,
qemu_iotests_check_cmd,
python,
args: args,
depends: qemu_iotests_binaries,
env: qemu_iotests_env,

View File

@ -30,7 +30,6 @@ class NetBSDVM(basevm.BaseVM):
"git-base",
"pkgconf",
"xz",
"python37",
"ninja-build",
# gnu tools
@ -66,7 +65,7 @@ class NetBSDVM(basevm.BaseVM):
mkdir src build; cd src;
tar -xf /dev/rld1a;
cd ../build
../src/configure --python=python3.7 --disable-opengl {configure_opts};
../src/configure --disable-opengl {configure_opts};
gmake --output-sync -j{jobs} {target} {verbose};
"""
poweroff = "/sbin/poweroff"