2 # kvm/qemu specific functions
4 ################################################################
6 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License version 2 or 3 as
10 # published by the Free Software Foundation.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program (see the file COPYING); if not, write to the
19 # Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 ################################################################
24 kvm_bin=/usr/bin/qemu-kvm
27 # assume virtio support by default
28 kvm_device=virtio-blk-pci
30 kvm_rng_device=virtio-rng-pci
36 printf "Error: %s\n" "$@" >&2
41 if ! grep -q -E '(kvm_rma_count.*kvm_hpt_count)|(kvm_hpt_count.*kvm_rma_count)' /proc/cmdline ; then
42 echo "put kvm_rma_count=<VM number> or kvm_hpt_count=<> to your boot options"
48 if ! grep -q "$HUGETLBFSPATH" /proc/mounts ; then
49 echo "hugetlbfs is not mounted to $HUGETLBFSPATH"
52 local HUGETLBBLKSIZE=$(stat -f -c "%S" "$HUGETLBFSPATH")
53 HUGETLBBLKSIZE=$(( ${HUGETLBBLKSIZE:-0} / 1024 ))
54 if test "$HUGETLBBLKSIZE" -lt 1 -o ! -e "/sys/kernel/mm/hugepages/hugepages-${HUGETLBBLKSIZE}kB" ; then
55 echo "could not determine hugetlbfs block size"
58 local PAGES_FREE=$(cat /sys/kernel/mm/hugepages/hugepages-${HUGETLBBLKSIZE}kB/free_hugepages)
59 local PAGES_REQ=$(( ${VM_MEMSIZE:-64} * 1024 / $HUGETLBBLKSIZE ))
60 if test "$PAGES_FREE" -lt "$PAGES_REQ" ; then
61 echo "expected $PAGES_REQ to be available (have $PAGES_FREE)"
62 echo "please adjust nr_hugepages"
67 vm_verify_options_kvm() {
71 # overwrite some options for specific host architectures
74 kvm_bin="/usr/bin/qemu-system-arm"
76 kvm_options="-enable-kvm -M virt -cpu host"
77 vm_kernel=/boot/zImage
78 vm_initrd=/boot/initrd
79 # prefer the guest kernel/initrd
80 test -e /boot/zImage.guest && vm_kernel=/boot/zImage.guest
81 test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest
82 kvm_device=virtio-blk-device
83 kvm_rng_device=virtio-rng-device
86 kvm_bin="/usr/bin/qemu-system-aarch64"
89 vm_initrd=/boot/initrd
90 if test "${BUILD_ARCH#aarch}" != "$BUILD_ARCH" -o "${BUILD_ARCH#armv8}" != "$BUILD_ARCH"; then
91 kvm_options="-enable-kvm -cpu host "
92 test -e /boot/Image.guest && vm_kernel=/boot/Image.guest
93 test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest
95 # Running an armv7 kernel on aarch64
96 kvm_options="-enable-kvm -cpu host,aarch64=off "
97 # prefer the guest kernel/initrd
98 test -e /boot/Image.guest32 && vm_kernel=/boot/Image.guest32
99 test -e /boot/initrd.guest32 && vm_initrd=/boot/initrd.guest32
101 # This option only exists with QEMU 2.5 or newer
102 if $kvm_bin -machine 'virt,?' 2>&1 | grep -q gic-version ; then
103 # We want to use the host gic version in order to make use
104 # of all available features (e.g. more than 8 CPUs) and avoid
105 # the emulation overhead of vGICv2 on a GICv3 host.
106 kvm_options+="-M virt,gic-version=host"
108 kvm_options+="-M virt"
110 kvm_device=virtio-blk-device
112 ppc|ppcle|ppc64|ppc64le)
113 kvm_bin="/usr/bin/qemu-system-ppc64"
115 kvm_options="-enable-kvm -M pseries"
116 grep -q PPC970MP /proc/cpuinfo && kvm_check_ppc970
117 vm_kernel=/boot/vmlinux
118 vm_initrd=/boot/initrd
119 if test "$BUILD_ARCH" = ppc64le -a -e /boot/vmlinuxle ; then
120 vm_kernel=/boot/vmlinuxle
121 vm_initrd=/boot/initrdle
123 grep -q "pSeries" /proc/cpuinfo && kvm_device=scsi-hd # no virtio on pSeries
124 grep -q "PowerNV" /proc/cpuinfo || kvm_device=scsi-hd # no virtio on ppc != power7 yet
127 kvm_bin="/usr/bin/qemu-system-s390x"
128 kvm_options="-enable-kvm"
130 vm_kernel=/boot/image
131 vm_initrd=/boot/initrd
132 kvm_device=virtio-blk-ccw
133 kvm_serial_device=virtio-serial-ccw
134 kvm_rng_device=virtio-rng-ccw
138 # check if we can run kvm
139 if ! test -r /dev/kvm -a -x "$kvm_bin" ; then
140 echo "host does not support kvm"
141 echo "either the kvm kernel-module is not loaded or kvm is not installed or hardware virtualization is deactivated in the BIOS."
146 test -n "$HUGETLBFSPATH" -a "$VM_TYPE" = kvm && kvm_check_hugetlb
149 test -n "$VM_KERNEL" && vm_kernel="$VM_KERNEL"
150 test -z "$vm_kernel" && vm_kernel=/boot/vmlinuz
153 test -n "$VM_INITRD" && vm_initrd="$VM_INITRD"
154 if test -z "$vm_initrd" ; then
155 # find a nice default
156 if test -e "/boot/initrd-build" ; then
157 vm_initrd="/boot/initrd-build"
158 elif test -e "/boot/initrd-virtio" ; then
159 vm_initrd="/boot/initrd-virtio"
161 vm_initrd="/boot/initrd"
163 # use /etc/sysconfig/kernel as indication if we have virtio
164 if test -e /etc/sysconfig/kernel ; then
165 local im=$(INITRD_MODULES=; . /etc/sysconfig/kernel; echo "$INITRD_MODULES")
166 if test "$im" != "${im/virtio/}" ; then
167 kvm_device=virtio-blk-pci
175 qemu_rootdev=/dev/disk/by-id/virtio-0
176 VM_SWAPDEV=/dev/disk/by-id/virtio-1
179 qemu_rootdev=/dev/sda
184 if test -n "$VM_NETOPT" -o -n "$VM_NETDEVOPT" ; then
185 if test -n "$VM_NETOPT" ; then
186 for item in "${VM_NETOPT[@]}" ; do
187 kvm_options="$kvm_options -net $item"
190 if test -n "$VM_NETDEVOPT" ; then
191 for item in "${VM_NETDEVOPT[@]}" ; do
192 kvm_options="$kvm_options -netdev $item"
197 if test -n "$VM_DEVICEOPT" ; then
198 for item in "${VM_DEVICEOPT[@]}" ; do
199 kvm_options="$kvm_options -device $item"
203 if test -n "$kvm_rng_device" ; then
204 if test -c /dev/hwrng &&
205 test -f /sys/class/misc/hw_random/rng_current &&
206 test "$(cat /sys/class/misc/hw_random/rng_current)" != none; then
209 rng_dev="/dev/random"
211 kvm_options="$kvm_options -object rng-random,filename=$rng_dev,id=rng0 -device $kvm_rng_device,rng=rng0"
217 qemu_args=(-drive file="$VM_IMAGE",format=raw,if=none,id=disk,serial=0,cache=unsafe -device "$kvm_device",drive=disk)
218 if [ -n "$VM_USER" ] ; then
219 getent passwd "$VM_USER" > /dev/null || complain 22 "cannot find KVM user '$VM_USER'"
221 # use qemu user by default if available
222 getent passwd qemu >/dev/null && VM_USER=qemu
224 [ -n "$VM_USER" ] && kvm_options="$kvm_options -runas $VM_USER"
225 if test -n "$VM_SWAP" ; then
226 qemu_args=("${qemu_args[@]}" -drive file="$VM_SWAP",format=raw,if=none,id=swap,serial=1,cache=unsafe -device "$kvm_device",drive=swap)
228 # the serial console device needs to be compiled into the target kernel
229 # which is why we can not use virtio-serial on other platforms
230 if test -n "$kvm_serial_device" ; then
231 qemu_args=("${qemu_args[@]}" -device "$kvm_serial_device" -device virtconsole,chardev=virtiocon0 -chardev stdio,id=virtiocon0)
232 elif test -n "$VM_CONSOLE_INPUT" ; then
233 qemu_args=("${qemu_args[@]}" -serial mon:stdio)
235 qemu_args=("${qemu_args[@]}" -serial stdio)
238 if test -n "$BUILD_JOBS" -a "$icecream" = 0 -a -z "$BUILD_THREADS" ; then
239 qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS")
240 elif test -n "$BUILD_JOBS" -a -n "$BUILD_THREADS" ; then
241 qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS,threads=$BUILD_THREADS")
243 if test "$VM_TYPE" = kvm ; then
244 test "$kvm_console" != ttyAMA0 && kvm_options="$kvm_options -cpu host"
245 test -n "$HUGETLBFSPATH" && kvm_options="$kvm_options -mem-prealloc -mem-path $HUGETLBFSPATH"
248 if test -n "$VMDISK_FILESYSTEM" ; then
249 qemu_rootfstype="rootfstype=$VMDISK_FILESYSTEM"
252 if test -n "$VMDISK_MOUNT_OPTIONS" ; then
253 qemu_rootflags="rootflags=${VMDISK_MOUNT_OPTIONS#-o }"
255 if test -z "$VM_NETOPT" -a -z "$VM_NETDEVOPT"; then
256 kvm_options="$kvm_options -net none"
258 if test -n "$VM_TELNET"; then
259 kvm_options="$kvm_options -netdev user,id=telnet,hostfwd=tcp:127.0.0.1:$VM_TELNET-:23 -device e1000,netdev=telnet"
261 set -- $qemu_bin -nodefaults -no-reboot -nographic -vga none $kvm_options \
264 -append "root=$qemu_rootdev $qemu_rootfstype $qemu_rootflags panic=1 quiet no-kvmclock nmi_watchdog=0 rw rd.driver.pre=binfmt_misc elevator=noop console=$kvm_console init=$vm_init_script" \
265 ${VM_MEMSIZE:+-m $VM_MEMSIZE} \
268 if test "$PERSONALITY" != 0 ; then
269 # have to switch back to PER_LINUX to make qemu work
272 export QEMU_AUDIO_DRV=none # we do not want to have sound inside the VMs
278 if ! fuser -k -TERM "$VM_IMAGE" ; then
279 echo "could not kill build in $VM_IMAGE"
285 # check if we will use a kernel from the build root, in this case
286 # we assume the kernel does virtio
287 if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then
288 # ide-hd is the non-virtio default
289 if test "$kvm_device" = ide-hd ; then
290 kvm_device=virtio-blk-pci
291 qemu_rootdev=/dev/disk/by-id/virtio-0
292 VM_SWAPDEV=/dev/disk/by-id/virtio-1
297 vm_attach_root_kvm() {
301 vm_attach_swap_kvm() {
305 vm_detach_root_kvm() {
309 vm_detach_swap_kvm() {