On 04.03.2016 13:16, Martin Pitt wrote: > Christian Seiler [2016-03-04 12:54 +0100]: >> - if x86_64 and default QEMU command: >> - if vmx in CPU flags: >> use -cpu kvm64,+vmx,+lahf_lm >> - else if svm in CPU flags: >> use -cpu kvm64,+svm,+lahf_lm >> - otherwise: don't pass -cpu >> >> That way, you have the same CPU on any hardware, with the exception >> of the vendor-specific VT extensions. >> >> If you're agreeable to that, I'll prepare a patch. > > Sounds great!
I've attached three patches: 0001-Support-nested-KVM-by-default-by-emulating-a-CPU-wit.patch This addresses the KVM issue. I've only done this for x86_64, because I don't think VMX extensions exist for pure x86_32 CPUs. Also, you can use an i386 VM image with x86_64, so I don't think this is an issue. Works fine here, both under Debian and Ubuntu. The other two patches are unrelated, but I noticed them while working on the code: 0002-setup-testbed-reduce-grub-timeout-on-Debian-systems.patch On Debian systems, grub has a default timeout of 5s - which means that boot of VM images is always delayed by that amount. This patch reduces that timeout to 1s to speed things up. I'm unsure about decreasing it to zero, because on Debian I know of now way of getting a grub menu if you really need it if the timeout is zero. But if you think a timeout of 0 is fine, feel free to change this. (I tested both locally, 0 also works.) 0003-adt-virt-qemu-make-i386-arch-work-by-default.patch On pure 32bit x86 systems adt-virt-qemu is currently broken, because os.uname()[4] is i686 typically, but the qemu binary ends in -i386. I've added a generic system to map architecture names. because I can easily imagine this also occurs for some other architectures. Reproducer is in the commit message (needs 32bit kernel + userland in VM image though!). Regards, Christian
From 245c2e8aa68b06bb83be6fad125a749690cc2a15 Mon Sep 17 00:00:00 2001 From: Christian Seiler <christ...@iwakd.de> Date: Fri, 4 Mar 2016 17:13:18 +0100 Subject: [PATCH 1/3] Support nested KVM by default by emulating a CPU with VMX/SVM support on x86_64. Implemented support for nested KVM by default on x86_64, if the default qemu command was specified and no CPU type was explicitly requested by the user. --- debian/changelog | 2 ++ virt-subproc/adt-virt-qemu | 28 +++++++++++++++++++++++++++- virt-subproc/adt-virt-qemu.1 | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 4d38b67..dc00b57 100644 --- a/debian/changelog +++ b/debian/changelog @@ -20,6 +20,8 @@ autopkgtest (3.19.4) UNRELEASED; urgency=medium [ Christian Seiler ] * adt-virt-qemu: Provide read-only version of the VM image to the test as /dev/baseimage, for tests that want to run nested QEMU. (Closes: #800845) + * Support nested KVM by default by emulating a CPU with VMX/SVM support on + x86_64. -- Martin Pitt <mp...@debian.org> Tue, 23 Feb 2016 18:21:51 +0100 diff --git a/virt-subproc/adt-virt-qemu b/virt-subproc/adt-virt-qemu index 9759c09..d53c94e 100755 --- a/virt-subproc/adt-virt-qemu +++ b/virt-subproc/adt-virt-qemu @@ -52,10 +52,11 @@ p_qemu = None ssh_port = None ssh_port_lock = None normal_user = None +qemu_cmd_default = None def parse_args(): - global args + global args, qemu_cmd_default parser = ArgumentParser() @@ -416,6 +417,22 @@ sys.exit(rc == 255 and 253 or rc) VirtSubproc.bomb('failed to connect to VM') +def get_cpuflags(): + try: + for line in open('/proc/cpuinfo', 'r'): + if line.startswith('flags\t') or line.startswith('flags '): + line = line.split() + else: + continue + if line[1] != ':': + continue + return line[2:] + return [] + except (IOError, OSError): + # fetching CPU flags isn't critical (only used to enable nested KVM), + # so don't fail here + return [] + def find_free_port(start): '''Find an unused port in the range [start, start+50)''' @@ -508,6 +525,15 @@ def hook_open(): if os.path.exists('/dev/kvm'): argv.append('-enable-kvm') + # Enable nested KVM by default on x86_64 + if os.uname()[4] == 'x86_64' and args.qemu_command == qemu_cmd_default and (not args.qemu_options or not '-cpu' in args.qemu_options.split()): + cpuflags = get_cpuflags() + if 'vmx' in cpuflags: + argv.append('-cpu') + argv.append('kvm64,+vmx,+lahf_lm') + elif 'svm' in cpuflags: + argv.append('-cpu') + argv.append('kvm64,+svm,+lahf_lm') # pass through option to qemu if args.qemu_options: diff --git a/virt-subproc/adt-virt-qemu.1 b/virt-subproc/adt-virt-qemu.1 index 5e3ec3d..17ef25b 100644 --- a/virt-subproc/adt-virt-qemu.1 +++ b/virt-subproc/adt-virt-qemu.1 @@ -145,6 +145,26 @@ build, which can cause a build failure if you are using a development series template. You will need to run \fBapt-get update\fR in the template yourself (e. g. using \fB\-\-setup\-commands\fR). +If the +.B --qemu-command +option has not been specified and no custom CPU type was selected in +.BR --qemu-options , +.B adt-virt-qemu +will try to enable nested KVM support by default on x86_64 platforms +if the hardware supports this. To fully enable this, one needs to +additionally set some module parameters on the host, by creating a file +.I /etc/modprobe.d/nested_kvm.conf +with the contents + +.EX +options kvm_intel nested=1 +options kvm_amd nested=1 +.EE + +and rebooting or reloading the KVM modules. It is still possible to use +QEMU in tests without this, albeit without hardware acceleration. On +Ubuntu systems these module options are typically already set. + .SH BUILDING IMAGES .SS Debian -- 2.5.0
From 263d345cff8f58495ff538356926ebec9f614585 Mon Sep 17 00:00:00 2001 From: Christian Seiler <christ...@iwakd.de> Date: Fri, 4 Mar 2016 17:51:42 +0100 Subject: [PATCH 2/3] setup-testbed: reduce grub timeout on Debian systems. --- debian/changelog | 1 + setup-commands/setup-testbed | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/debian/changelog b/debian/changelog index dc00b57..28c00c0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -22,6 +22,7 @@ autopkgtest (3.19.4) UNRELEASED; urgency=medium /dev/baseimage, for tests that want to run nested QEMU. (Closes: #800845) * Support nested KVM by default by emulating a CPU with VMX/SVM support on x86_64. + * setup-testbed: reduce grub timeout on Debian systems. -- Martin Pitt <mp...@debian.org> Tue, 23 Feb 2016 18:21:51 +0100 diff --git a/setup-commands/setup-testbed b/setup-commands/setup-testbed index b7f586f..2a7dec5 100755 --- a/setup-commands/setup-testbed +++ b/setup-commands/setup-testbed @@ -82,6 +82,10 @@ if [ -z "${ADT_IS_SETUP_COMMAND:-}" ] && [ ! -e "$root/etc/default/grub.d/90-aut sed -i '/CMDLINE_LINUX_DEFAULT/ s/"$/ console=ttyS0"/' "$root/etc/default/grub" changed=1 fi + if ! grep -q GRUB_HIDDEN_TIMEOUT=0 "$root/etc/default/grub" ; then + sed -i '/^GRUB_TIMEOUT=/ s/=.*$/=1/' "$root/etc/default/grub" + changed=1 + fi fi [ -z "${changed:-}" ] || chroot "$root" update-grub || echo "WARNING: update-grub failed!" fi -- 2.5.0
From 16cb53f68586c65d024de78578653e4ec3fa56ea Mon Sep 17 00:00:00 2001 From: Christian Seiler <christ...@iwakd.de> Date: Fri, 4 Mar 2016 18:03:54 +0100 Subject: [PATCH 3/3] adt-virt-qemu: make i386 arch work by default. os.uname returns e.g. i686 instead of i386, but the qemu command is called qemu-system-i386. Handle that and add support for generic mappings for future similar cases. Reproducer: setarch i386 adt-run ... --- adt-virt-qemu image --- debian/changelog | 1 + virt-subproc/adt-virt-qemu | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 28c00c0..3a6d8c1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -23,6 +23,7 @@ autopkgtest (3.19.4) UNRELEASED; urgency=medium * Support nested KVM by default by emulating a CPU with VMX/SVM support on x86_64. * setup-testbed: reduce grub timeout on Debian systems. + * adt-virt-qemu: make i386 arch work by default. -- Martin Pitt <mp...@debian.org> Tue, 23 Feb 2016 18:21:51 +0100 diff --git a/virt-subproc/adt-virt-qemu b/virt-subproc/adt-virt-qemu index d53c94e..758f9b1 100755 --- a/virt-subproc/adt-virt-qemu +++ b/virt-subproc/adt-virt-qemu @@ -34,6 +34,7 @@ import time import socket import errno import fcntl +import re try: our_base = os.environ['AUTOPKGTEST_BASE'] + '/lib' @@ -58,9 +59,19 @@ qemu_cmd_default = None def parse_args(): global args, qemu_cmd_default - parser = ArgumentParser() + mappings = { 'i[3456]86': 'i386' } + arch = os.uname()[4] + qemu_arch = None + for pattern, real_name in mappings.items(): + if re.match('^' + pattern + '$', arch): + qemu_arch = real_name + break + if qemu_arch is None: + qemu_arch = arch - qemu_cmd_default = 'qemu-system-' + os.uname()[4] + qemu_cmd_default = 'qemu-system-' + qemu_arch + + parser = ArgumentParser() parser.add_argument('-q', '--qemu-command', default=qemu_cmd_default, help='QEMU command (default: %s)' % qemu_cmd_default) -- 2.5.0
signature.asc
Description: OpenPGP digital signature