aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWen Jin <wenx.jin@intel.com>2015-12-24 11:05:23 +0800
committerAndi Kleen <ak@linux.intel.com>2015-12-25 19:39:09 -0800
commitf3df4b7daec9c8535b6407e1328572fd0af3022b (patch)
treee6cf84e8ae0e27b63949bfa51bf63fee62ff192e
parentac82804edef3137aa153838c038d35f7e80f50f9 (diff)
downloadmce-test-f3df4b7daec9c8535b6407e1328572fd0af3022b.tar.gz
Support SRAR error injection in QEMU/KVM
This patch is used to test SRAR error recovery in QEMU/KVM. Meanwhile. It uses EINJ to substitute mce-inject as injection tool to ensure error happended in QEMU context. Minor update by Gong. Signed-off-by: Wen Jin <wenx.jin@intel.com> Signed-off-by: Chen, Gong <gong.chen@linux.intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com>
-rw-r--r--cases/function/kvm/README207
-rw-r--r--[-rwxr-xr-x]cases/function/kvm/guest/guest_run_simple.sh (renamed from cases/function/kvm/guest/guest_run.sh)15
-rw-r--r--cases/function/kvm/guest/guest_run_victim.sh38
-rwxr-xr-xcases/function/kvm/host/host_run.sh353
-rw-r--r--cases/function/kvm/patches/p2v.patch94
-rw-r--r--tools/simple_process/simple_process.c17
6 files changed, 485 insertions, 239 deletions
diff --git a/cases/function/kvm/README b/cases/function/kvm/README
index d79fb52..938bbbc 100644
--- a/cases/function/kvm/README
+++ b/cases/function/kvm/README
@@ -1,12 +1,10 @@
KVM RAS Test Suite
==================
-The KVM RAS Test Suite is a collection of test scripts for testing the
-Linux kernel MCE processing features in KVM guest system.
-
-Jan 26th, 2010
-
-Jiajia Zheng
+The KVM RAS Test Suite is a collection of test scripts for testing
+Linux kernel MCE processing features in QEMU/KVM.
+Jiajia Zheng, Jan 26th, 2010
+Updated by Wen Jin <wenx.jin@intel.com>, 2015-12-08
In the Package
----------------
@@ -25,28 +23,49 @@ KVM RAS Test Suite has following dependencies on kernel and other tools:
* Linux Kernel:
Version 2.6.32 or newer, with MCA high level handlers enabled.
+ To test LMCE(Local MCE), kernel 4.3+ is needed.
* mce-inject
- A tool to inject mce error into kernel
+ A tool to inject MCE error(spoof) into kernel.
+
+* mcelog
+ A tool that must be installed on both host and guest system to collect
+ logs related to MCE error. Ensure mcelog always running in daemon mode
+ on guest system after booting up. Please always use latest version.
+
+ You can get it from here:
+ git://git.kernel.org/pub/scm/utils/cpu/mce/mcelog.git
+ https://git.kernel.org/pub/scm/utils/cpu/mce/mcelog.git
* page-types:
- A tool to query page types, which is accompanied with Linux kernel
- source (2.6.32 or newer, $KERNEL_SRC/Documentation/vm/page-types.c).
+ A tool to query page types, which is accompanied by Linux kernel
+ source (2.6.32+, $KERNEL_SRC/Documentation/vm/page-types.c or
+ 3.3+ $KERNEL_SRC/tools/vm/page-types.c).
* simple_process:
- A process constantly access the allocated memeory. (../tools/simple_process)
+ A process constantly access the allocated memeory.
+ Located under mce-test/tools/simple_process/.
+
+* victim
+ Play a role like *simple_process* but more powerful.
+
+* qemu-img:
+ QEMU disk image utility.
+
+* qemu-nbd:
+ A tool to mount QEMU disk image(i.e. qcow2) with NBD protocol.
* kpartx:
- A tool to list partition mappings from partition tables
+ A tool to list partition mappings from partition tables.
* (optionally) losetup
- A tool to set up and control loop devices
+ A tool to set up and control loop devices.
* (optionally) pvdisplay/vgchange:
- A tool to display/change physical volume attribute
+ A tool to display/change physical volume attribute.
* (optionally) ssh-keygen
- A tool to provide the authentication key generation, management and conversion
+ A tool to provide the authentication key generation, management and conversion.
Test method
---------------
@@ -54,15 +73,45 @@ Test method
- Translate this address untill we get the physical address on the host OS
-- Software injects an SRAO MCE at that physical address from host OS
+- Software injects an SRAO error via mce-inject on that physical address from host OS
-- (optionally) Write to the address from the guest, i.e attempt to
+- Or inject an SRAR error via EINJ at that physical address from host OS
+
+- (optionally) Read/Write on the same address from the guest, i.e. attempt to
write to the poisoned page from the guest.
-the expected result:
+- NOTE: SRAR error must be injected via EINJ rather than mce-inject. It is because
+ SRAR error can be generated only in the process context in which it is triggered,
+ so if injected via mce-inject, the error is triggered in mce-inject execution
+ context but not in QEMU's. Host kernel will not send signal SRAR to QEMU.
+ On the other hand, if injected via EINJ in host but triggered in VM/QEMU,
+ QEMU can receive signal SRAR correctly from host kernel.
-HOST system dmesg:
+The test command and expected result, i.e, lists as below:
+----------------
+
+1. for SRAO error:
+
+bash> ./host_run.sh -t spoof -i test.qcow2 -f SRAO
+ 2 logical volume(s) in volume group "VolGroup" now active
+mount LVM image to /tmp/tmp.qFt9RbQhkk
+ 0 logical volume(s) in volume group "VolGroup" now active
+/dev/nbd0 disconnected
+Start the default kernel on guest system,test.qcow2
+monitor console is /dev/pts/0
+serial console is /dev/pts/1
+Waiting for guest system start up...
+Guest physical address is 0x6e0a7000
+Host virtual address is 7fbfe9ea7
+Host physical address is 0x8092a7000
+calling mce-inject /root/mce-test/cases/function/kvm/host/mce_inject_data
+Guest physical klog address is 0x6e0a7
+localhost.localdomain login: MCE 0x6e0a7: Killing simple_process:3230 due to hardware memory corruption
+MCE 0x6e0a7: recovery action for dirty LRU page: Recovered
+PASS: Inject error into guest!
+PASS: Guest System alive!
+HOST system dmesg:
...
Machine check injector initialized
Triggering MCE exception on CPU 0
@@ -73,7 +122,6 @@ MCE 0x806324: Killing qemu-system-x86:8829 early due to hardware memory corrupti
MCE 0x806324: dirty LRU page recovery: Recovered
...
-
GUEST system dmesg:
...
[Hardware Error]: Machine check events logged
@@ -81,6 +129,64 @@ MCE 0x75925: Killing simple_process:2273 early due to hardware memory corruption
MCE 0x75925: dirty LRU page recovery : Recovered
...
+2. for SRAR error:
+
+bash> ./host_run.sh -t real -i test.qcow2
+ 2 logical volume(s) in volume group "VolGroup" now active
+mount LVM image to /tmp/tmp.2wbxFrY3Sd
+ 0 logical volume(s) in volume group "VolGroup" now active
+/dev/nbd0 disconnected
+Start the default kernel on guest system,test.qcow2
+monitor console is /dev/pts/0
+serial console is /dev/pts/1
+Waiting for guest system start up...
+Guest physical address is 0x6e3a0000
+Host virtual address is 0x7fb1f21a0000
+Host physical address is 0x4225a0000
+calling apei_inj 0x4225a0000
+SRAR error triggered successfully
+LMCE happens
+PASS: Inject error into guest!
+PASS: Guest System alive!
+
+Host mcelog information:
+
+Hardware event. This is not a software error.
+MCE 0
+CPU 2 BANK 1 TSC 76f903d0667e
+MISC 86 ADDR 4225a0000
+TIME 1446728506 Thu Nov 5 08:01:46 2015
+MCG status:RIPV EIPV MCIP
+MCi status:
+Uncorrected error
+Error enabled
+MCi_MISC register valid
+MCi_ADDR register valid
+SRAR
+MCA: Data CACHE Level-0 Data-Read Error
+STATUS bd80002000100134 MCGSTATUS 7
+MCGCAP 7000c16 APICID 4 SOCKETID 0
+CPUID Vendor Intel Family 6 Model 63
+
+Guest mcelog information:
+
+Hardware event. This is not a software error.
+MCE 0
+CPU 1 BANK 9 TSC 22b34556c4
+RIP 33:401311
+MISC 8c ADDR 6e3a0000
+TIME 1446728507 Thu Nov 5 08:01:47 2015
+MCG status:EIPV MCIP LMCE
+MCi status:
+Uncorrected error
+Error enabled
+MCi_MISC register valid
+MCi_ADDR register valid
+SRAR
+MCA: Data CACHE Level-0 Data-Read Error
+STATUS bd80000000000134 MCGSTATUS e
+MCGCAP 900010a APICID 1 SOCKETID 1
+CPUID Vendor Intel Family 6 Model 60
Installation
---------------
@@ -95,50 +201,49 @@ Installation
CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
CONFIG_MEMORY_FAILURE=y
- NOTE: if the host machine doesn't support software error recovery
+ NOTE: if host machine doesn't support software error recovery
(MCG_SER_P in IA32_MCG_CAP[24]), please apply the patch fake_ser_p.patch
under ./patches/
2. Use ssh-keygen to generate public and privite keys on the host OS,
and copy id_rsa and id_rsa.pub from ~/.ssh/ into the testing directory
on the host system.
-3. compile and install qemu-kvm
- the qemu-kvm source can be got from git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git.
- Before compile qemu-kvm, a patch p2v.patch should be applied. This patch
- is located under ./patches/
+3. compile and install QEMU
+ The QEMU source can be got from git://git.qemu-project.org/qemu.git.
+ To build QEMU, under QEMU directory, run ./configure --target-list=x86_64-softmmu
+ --disable-strip, and then make;make install.
Please ensure *SDL-devel* library is installed on the host machine, otherwise
- only VNC can be used substituing local graphic output.
-4. install the guest OS on the qemu
- e.g.
+ only VNC can be used to substitue local graphic output.
+4. install the guest OS on the QEMU
+ e.g.
step 1: qemu-img create -f qcow2 test.img 10G
step 2: qemu-system-x86_64 -hda ./test.img -m 2048 -cdrom rhel6.iso -boot d
after the installation, please be sure to execute the following check:
a) add necessary command line parameters under your boot item.
- This is to enable console output redirection to the serial.
- e.g.
- before:
- title Red Hat Enterprise Linux Server (2.6.32kvm)
- root (hd0,1)
- kernel /boot/vmlinuz-2.6.32kvm ro root=/dev/sda1
- initrd /boot/initramfs-2.6.32kvm.img
- after:
- title Red Hat Enterprise Linux Server (2.6.32kvm)
- root (hd0,1)
- kernel /boot/vmlinuz-2.6.32kvm ro root=/dev/sda1 console=tty0 console=ttyS0,115200n8
- initrd /boot/initramfs-2.6.32kvm.img
+ This is to enable console output redirection to the serial.
+ e.g.
+ before:
+ title Red Hat Enterprise Linux Server (2.6.32kvm)
+ root (hd0,1)
+ kernel /boot/vmlinuz-2.6.32kvm ro root=/dev/sda1
+ initrd /boot/initramfs-2.6.32kvm.img
+ after:
+ title Red Hat Enterprise Linux Server (2.6.32kvm)
+ root (hd0,1)
+ kernel /boot/vmlinuz-2.6.32kvm ro root=/dev/sda1 console=tty0 console=ttyS0,115200n8
+ initrd /boot/initramfs-2.6.32kvm.img
b) DHCP guest ethernet card. This operation is to ensure the network connection
- is OK.
- e.g.
- bash> dhclient eth0
+ is OK.
+ e.g.
+ bash> dhclient eth0
c) enable SSH public/private key authorization, otherwise, the SSH connection password
- is necessary to be provided in the test progress.
- please check /etc/ssh/ssd_config and ensure related options are opened.
- e.g.
- RSAAuthentication yes
- PubkeyAuthentication yes
- after the related options are opened, please restart ssh service
- e.g.
- bash> service sshd restart
-
+ is necessary to be provided in the test progress.
+ please check /etc/ssh/ssd_config and ensure related options are opened.
+ e.g.
+ RSAAuthentication yes
+ PubkeyAuthentication yes
+ after the related options are opened, please restart ssh service
+ e.g.
+ bash> service sshd restart
Start Testing
---------------
diff --git a/cases/function/kvm/guest/guest_run.sh b/cases/function/kvm/guest/guest_run_simple.sh
index 0f5886b..fe72819 100755..100644
--- a/cases/function/kvm/guest/guest_run.sh
+++ b/cases/function/kvm/guest/guest_run_simple.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Test script for KVM RAS
+# Test script for SRAO error injection
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
@@ -21,12 +21,19 @@
#
killall simple_process
+cat /dev/null > /var/log/mcelog
+sleep 1
-cd GUEST_DIR
+cd GUEST_DIR/simple_process
+gcc -o simple_process simple_process.c
+cd ../page-types
+gcc -o page-types page-types.c
+cd ..
-./simple_process > /dev/null &
+./simple_process/simple_process > /dev/null &
+sleep 1
-./page-types -p `pidof simple_process` -LN -b anon > guest_page
+./page-types/page-types -p `pidof simple_process` -LN -b anon > guest_page
if [ -s guest_page ]; then
ADDR_KLOG=`awk 'NR > 3 {print "0x"$2}' guest_page | sed -n -e '1p'`
ADDR=`echo $ADDR_KLOG"000"`
diff --git a/cases/function/kvm/guest/guest_run_victim.sh b/cases/function/kvm/guest/guest_run_victim.sh
new file mode 100644
index 0000000..4743aa3
--- /dev/null
+++ b/cases/function/kvm/guest/guest_run_victim.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+# Test script for SRAR error injection
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; version
+# 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should find a copy of v2 of the GNU General Public License somewhere
+# on your Linux system; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Copyright (C) 2015, Intel Corp.
+# Author: Wen Jin <wenx.jin@intel.com>
+#
+
+killall victim
+cat /dev/null > /var/log/mcelog
+sleep 1
+
+cd GUEST_DIR/victim
+gcc -o victim victim.c
+cd ..
+
+./victim/victim -k 0 -d > guest_phys &
+sleep 1
+
+if [ -s guest_phys ]; then
+ ADDR=`cat guest_phys | awk '{print $NF}'`
+ echo "guest physical address is $ADDR" > guest_tmp
+fi
+
diff --git a/cases/function/kvm/host/host_run.sh b/cases/function/kvm/host/host_run.sh
index 500e275..f17b25a 100755
--- a/cases/function/kvm/host/host_run.sh
+++ b/cases/function/kvm/host/host_run.sh
@@ -16,10 +16,73 @@
# on your Linux system; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
-# Copyright (C) 2010, Intel Corp.
+# Copyright (C) 2010-2015, Intel Corp.
# Author: Jiajia Zheng <jiajia.zheng@intel.com>
+# Author: Wen Jin <wenx.jin@intel.com>
#
+export ROOT=`(cd ../../../../; pwd)`
+
+. $ROOT/lib/functions.sh
+setup_path
+. $ROOT/lib/mce.sh
+
+inject_type=0x00000010
+EDAC_TYPE=""
+g_debugfs=""
+
+complain()
+{
+ echo $*
+ exit 1
+}
+
+apei_inj()
+{
+ echo $inject_type > $g_debugfs/apei/einj/error_type
+ echo $1 > $g_debugfs/apei/einj/param1
+ echo 0xfffffffffffff000 > $g_debugfs/apei/einj/param2
+ echo 1 > $g_debugfs/apei/einj/notrigger
+ echo 1 > $g_debugfs/apei/einj/error_inject
+}
+
+check_einj()
+{
+ check_debugfs
+
+ g_debugfs=`cat /proc/mounts | grep debugfs | cut -d ' ' -f2 | head -1`
+ #if einj is not builtin, just insmod it
+ if [ ! -d $g_debugfs/apei/einj ]; then
+ #if einj is a module, it is ensured to have been loaded
+ modprobe einj param_extension=1 > /dev/null 2>&1
+ [ $? -eq 0 ] || complain "module einj isn't supported?"
+ fi
+ [ -f $g_debugfs/apei/einj/param1 ] || complain "No BIOS extension support for APEI on this platform"
+ [ -f $g_debugfs/apei/einj/notrigger ] ||
+ complain "No parameter *notrigger*. Injection maybe causes system crash. Please check commit v3.3-3-gee49089"
+
+ #check if the platform supports Uncorrectable non-fatal Memory Error injection
+ cat $g_debugfs/apei/einj/available_error_type | grep -q $inject_type
+ if [ $? -ne 0 ]; then
+ complain "Uncorrectable non-fatal Memory Error is not supported"
+ fi
+}
+
+rm_edac()
+{
+ # remove possible EDAC module, otherwise, the error information will be ate
+ # by EDAC module and mcelog will not get it.
+ # By now, only i7core_edac and sb_edac hook into the mcelog kernel buffer
+ cat /proc/modules | grep -q i7core_edac
+ if [ $? -eq 0 ]; then
+ EDAC_TYPE="i7core_edac"
+ else
+ cat /proc/modules | grep -q sb_edac
+ [ $? -eq 0 ] && EDAC_TYPE="sb_edac"
+ fi
+ rmmod $EDAC_TYPE >/dev/null 2>&1
+}
+
image=""
mce_inject_file=""
@@ -31,25 +94,29 @@ RAM_size=""
kernel=""
initrd=""
root=""
+test_type=""
+format=""
+trigger_file="trigger_start"
usage()
{
echo "Usage: ./host_run.sh [-options] [arguments]"
echo "================Below are the must have options==============="
+ echo -e "\t-t test_type\t: spoof(mce_inject) or real(einj)"
echo -e "\t-i image\t: guest image"
- echo -e "\t-f mcefile\t: which mce data file to inject"
echo "================Below are the optional options================"
+ echo -e "\t-f mcefile\t: which mce data file to inject"
echo -e "\t-d hostdir\t: where you put the test scripts on host system"
echo -e "\t\t\tBe careful to change it"
echo -e "\t-g guestdir\t: where you put the test scripts on guest system"
echo -e "\t\t\tBy default, guestdir is set to $GUEST_DIR"
echo -e "\t-o offset\t: guest image offset"
echo -e "\t\t\tBy default, offset is calculated by kpartx "
- echo -e "\t-l\t\t: late kill, disable early kill in guest system"
- echo -e "\t\t\tBy default, earlykill is enabled "
- echo -e "\t-m ramsize\t: virtual RAM size of guest system"
- echo -e "\t\t\tBy default, qemu-kvm defaults to 512M bytes"
- echo -e "\t-h\t\t: show this help"
+ echo -e "\t-l\t\t: late kill, disable early kill in guest system"
+ echo -e "\t\t\tBy default, earlykill is enabled "
+ echo -e "\t-m ramsize\t: virtual RAM size of guest system"
+ echo -e "\t\t\tBy default, qemu-kvm defaults to 2048M bytes"
+ echo -e "\t-h\t\t: show this help"
echo "============If you want to specify the guest kernel==========="
echo "============please set below options all together============="
echo -e "\t-k kernel\t: guest kernel"
@@ -58,9 +125,10 @@ usage()
exit 0
}
-while getopts "i:f:d:g:o:b:p:k:n:r:hlm:" option
+while getopts "i:f:d:g:o:b:p:k:n:r:t:hlm:" option
do
- case $option in
+ case $option in
+ t) test_type=$OPTARG;;
i) image=$OPTARG;;
f) mce_inject_file=$OPTARG;;
d) HOST_DIR=$OPTARG;;
@@ -73,11 +141,13 @@ do
m) RAM_size=$OPTARG;;
h) usage;;
*) echo 'invalid option!'; usage;;
- esac
+ esac
done
-
-guest_script=$GUEST_DIR/guest_run.sh
+script_simple=guest_run_simple.sh
+script_victim=guest_run_victim.sh
+guest_script_simple=$GUEST_DIR/$script_simple
+guest_script_victim=$GUEST_DIR/$script_victim
guest_tmp=$GUEST_DIR/guest_tmp
guest_page=$GUEST_DIR/guest_page
GUEST_PHY=""
@@ -93,7 +163,8 @@ host_tmp=$HOST_DIR/host_tmp
mce_inject_data=$HOST_DIR/mce_inject_data
monitor_console=""
serial_console=""
-
+NBD_MAJOR="43"
+NBD_DEV="/dev/nbd0"
invalid()
{
@@ -109,37 +180,78 @@ check_env()
exit 1
fi
- if modinfo mce_inject &> /dev/null; then
+ if modinfo mce_inject >/dev/null 2>&1; then
if ! lsmod | grep -q mce_inject; then
if ! modprobe mce_inject; then
- invalid "module mce_inject isn't supported ?"
+ complain "module mce_inject isn't supported ?"
fi
fi
fi
- which kpartx &>/dev/null
- [ ! $? -eq 0 ] && invalid "please install kpartx tool!"
- which mce-inject &>/dev/null
- [ ! $? -eq 0 ] && invalid "please install mce-inject tool!"
-
- [ -z $RAM_size ] && RAM_size=512
- [ -z $image ] && invalid "please input the guest image!"
- [ ! -e $image ] && invalid "guest image $image does not exist!"
- [ -z $mce_inject_file ] && invalid "please input the mce data file!"
- [ ! -e $mce_inject_file ] && invalid "mce data file $mce_inject_file does not exist!"
+ which qemu-img >/dev/null 2>&1
+ [ ! $? -eq 0 ] && complain "please install qemu-img tool!"
+ which kpartx >/dev/null 2>&1
+ [ ! $? -eq 0 ] && complain "please install kpartx tool!"
+ which losetup >/dev/null 2>&1
+ [ ! $? -eq 0 ] && complain "please install losetup tool!"
+ which pvdisplay >/dev/null 2>&1
+ [ ! $? -eq 0 ] && complain "please install pvdisplay tool!"
+ which vgchange >/dev/null 2>&1
+ [ ! $? -eq 0 ] && complain "please install vgchange tool!"
+ which mce-inject >/dev/null 2>&1
+ [ ! $? -eq 0 ] && complain "please install mce-inject tool!"
+
+ [ -z $RAM_size ] && RAM_size=2048
+ if [ -z $test_type ] || [ "$test_type" != "spoof" ] && [ "$test_type" != "real" ]
+ then
+ invalid "please input inject type: spoof or real!"
+ fi
+ [ -z ${image} ] && invalid "please input the guest image!"
+ [ ! -e ${image} ] && invalid "guest image ${image} does not exist!"
+ if [ "$test_type" == "spoof" ]; then
+ [ -z $mce_inject_file ] && invalid "please input the mce data file!"
+ [ ! -e $mce_inject_file ] && invalid "mce data file $mce_inject_file does not exist!"
+ fi
- [ ! -e $host_key_pub ] && invalid "host public key does not exist!"
- [ ! -e $host_key_priv ] && invalid "host privite key does not exist!"
+ [ ! -e $host_key_pub ] && complain "host public key does not exist!"
+ [ ! -e $host_key_priv ] && complain "host privite key does not exist!"
chmod 600 $host_key_pub
chmod 600 $host_key_priv
+ if [ "$test_type" == "real" ]; then
+ [ -e $ROOT/bin/victim ] || complain "file victim does not exist!" \
+ "maybe you forget to run make install under directory $ROOT before test"
+ check_einj
+ rm_edac
+ elif [ "$test_type" == "spoof" ]; then
+ [ -e $ROOT/bin/page-types ] || complain "file page-types does not exist!"\
+ "maybe you forget to run make install under directory $ROOT before test"
+ fi
}
mount_image()
{
+ local filename
+
mnt=`mktemp -d`
- offset=`kpartx -l $image | awk '/loop deleted/ {next}; \
+ filename=${image}
+ format=`qemu-img info ${image} | awk -F ': ' '/file format/ {print $NF}'`
+ if [ "$format" != "raw" ]; then
+ which qemu-nbd >/dev/null 2>&1
+ [ ! $? -eq 0 ] && complain "please install qemu-nbd tool!"
+ if [ ! -b $NBD_DEV ] || [ `ls -l $NBD_DEV | awk '{print $5}' | cut -b 1-2` != $NBD_MAJOR ]; then
+ modprobe nbd >/dev/null 2>&1
+ [ $? -eq 0 ] || complain "module nbd isn't supported?"
+ fi
+ qemu-nbd -d $NBD_DEV
+ sleep 1
+ qemu-nbd -c $NBD_DEV ${image}
+ sleep 1
+ filename=$NBD_DEV
+ fi
+
+ offset=`kpartx -l ${filename} | awk '/loop deleted/ {next}; \
{offset=$NF*512}; END {print offset}'`
- mount_err=`mount -oloop,offset=$offset $image $mnt 2>&1`
+ mount_err=`mount -oloop,offset=$offset ${filename} $mnt 2>&1`
if [ $? -eq 0 ]; then
fs_type=unset
echo "mount image to $mnt"
@@ -148,40 +260,61 @@ mount_image()
#See if we're dealing with a LVM filesystem type
fs_type=`echo $mount_err | awk '/^mount: unknown filesystem type/ {print $NF}'`
- if [ $fs_type != "'LVM2_member'" ]; then
+ if [ "$fs_type" != "'LVM2_member'" ]; then
echo unknown filesystem type
rm -rf $mnt
+ if [ "$format" != "raw" ]; then
+ qemu-nbd -d $NBD_DEV
+ fi
return 1
fi
- which losetup &>/dev/null
- [ ! $? -eq 0 ] && invalid "please install losetup tool!"
- which pvdisplay &>/dev/null
- [ ! $? -eq 0 ] && invalid "please install pvdisplay tool!"
- which vgchange &>/dev/null
- [ ! $? -eq 0 ] && invalid "please install vgchange tool!"
-
#Try mounting the LVM image
- loop_dev=`losetup -o ${offset} -f --show ${image}`
- if [ -z ${loop_dev} ]; then
+ loop_dev=`losetup -o ${offset} -f --show ${filename}`
+ sleep 1
+ if [ -z "${loop_dev}" ]; then
echo no available loop device
rm -rf $mnt
+ if [ "$format" != "raw" ]; then
+ qemu-nbd -d $NBD_DEV
+ fi
return 1
fi
+
vg=`pvdisplay ${loop_dev} | awk '/ VG Name/ {print $NF}'`
- lv=lv_root
+ if [ -z "${vg}" ]; then
+ losetup -d ${loop_dev}
+ rm -rf $mnt
+ if [ "$format" != "raw" ]; then
+ qemu-nbd -d $NBD_DEV
+ fi
+ return 1
+ fi
+
vgchange -a ey ${vg}
- if [ ! -b /dev/mapper/${vg}-${lv} ]; then
+ sleep 1
+ #The device name under the /dev/mapper directory consists of vg(volume group) name
+ #and lv(logical volume) name, in which the char '-' will be replaced with "--"
+ #in the vg name part if it exists.
+ devmap_vg=`echo ${vg} | sed 's/-/--/g'`
+ devmap_root=`find /dev/mapper -name "${devmap_vg}*root" -print`
+ if [ ! -b "${devmap_root}" ]; then
echo '! block special'
losetup -d ${loop_dev}
rm -rf $mnt
+ if [ "$format" != "raw" ]; then
+ qemu-nbd -d $NBD_DEV
+ fi
return 1
fi
- mount /dev/mapper/${vg}-${lv} $mnt
+ mount ${devmap_root} $mnt
if [ $? -ne 0 ]; then
vgchange -a en ${vg}
losetup -d ${loop_dev}
rm -rf $mnt
+ if [ "$format" != "raw" ]; then
+ qemu-nbd -d $NBD_DEV
+ fi
return 1
fi
echo "mount LVM image to $mnt"
@@ -192,11 +325,14 @@ umount_image()
{
umount $mnt
sleep 2
- if [ $fs_type = "'LVM2_member'" ]; then
+ if [ "$fs_type" = "'LVM2_member'" ]; then
vgchange -a en ${vg}
losetup -d ${loop_dev}
fi
rm -rf $mnt
+ if [ "$format" != "raw" ]; then
+ qemu-nbd -d $NBD_DEV
+ fi
}
#Guest Image Preparation
@@ -218,16 +354,26 @@ image_prepare()
chmod 700 $mnt/root/.ssh
fi
mkdir -p $mnt/$GUEST_DIR
- cp ../guest/guest_run.sh $mnt/$GUEST_DIR
- gcc -o simple_process ../../tools/simple_process/simple_process.c
- gcc -o page-types ../../tools/page-types.c
- cp simple_process $mnt/$GUEST_DIR
- cp page-types $mnt/$GUEST_DIR
- sed -i -e "s#GUEST_DIR#$GUEST_DIR#g" $mnt/$guest_script
+ if [ "$test_type" == "real" ]; then
+ rm -f $mnt/$GUEST_DIR/$trigger_file
+ cp -f ../guest/$script_victim $mnt/$GUEST_DIR
+ cp -rf $ROOT/tools/victim $mnt/$GUEST_DIR
+ elif [ "$test_type" == "spoof" ]; then
+ cp -f ../guest/$script_simple $mnt/$GUEST_DIR
+ cp -rf $ROOT/tools/simple_process $mnt/$GUEST_DIR
+ cp -rf $ROOT/tools/page-types $mnt/$GUEST_DIR
+ fi
cat $host_key_pub >> $mnt/root/.ssh/authorized_keys
- kvm_ras=/etc/init.d/kvm_ras
- sed -e "s#EARLYKILL#$early_kill#g" \
- -e "s#GUESTRUN#$guest_script#g" $guest_init > $mnt/$kvm_ras
+ kvm_ras=/etc/init.d/kvm_ras
+ if [ "$test_type" == "real" ]; then
+ sed -i -e "s#GUEST_DIR#$GUEST_DIR#g" $mnt/$guest_script_victim
+ sed -e "s#EARLYKILL#$early_kill#g" \
+ -e "s#GUESTRUN#$guest_script_victim#g" $guest_init > $mnt/$kvm_ras
+ elif [ "$test_type" == "spoof" ]; then
+ sed -i -e "s#GUEST_DIR#$GUEST_DIR#g" $mnt/$guest_script_simple
+ sed -e "s#EARLYKILL#$early_kill#g" \
+ -e "s#GUESTRUN#$guest_script_simple#g" $guest_init > $mnt/$kvm_ras
+ fi
chmod a+x $mnt/$kvm_ras
ln -s $kvm_ras $mnt/etc/rc${i}.d/S99kvm_ras
sleep 2
@@ -242,7 +388,7 @@ start_guest()
if [ ! -z $initrd ]; then
if [ ! -z $root ]; then
append="root=$root ro loglevel=8 mce=3 console=ttyS0,115200n8 console=tty0"
- qemu-system-x86_64 -hda $image -kernel $kernel -initrd $initrd --append "$append" \
+ qemu-system-x86_64 -hda ${image} -kernel $kernel -initrd $initrd --append "$append" \
-m $RAM_size -net nic,model=rtl8139 -net user,hostfwd=tcp::5555-:22 \
-monitor pty -serial pty -pidfile $pid_file > $host_start 2>&1 &
sleep 5
@@ -253,14 +399,14 @@ start_guest()
invalid "please specify the guest initrd!"
fi
else
- echo "Start the default kernel on guest system"
- qemu-system-x86_64 -hda $image \
+ echo "Start the default kernel on guest system,${image}"
+ qemu-system-x86_64 -smp 2 -machine accel=kvm -drive file=${image},format=$format \
-m $RAM_size -net nic,model=rtl8139 -net user,hostfwd=tcp::5555-:22 \
-monitor pty -serial pty -pidfile $pid_file > $host_start 2>&1 &
- sleep 5
+ sleep 10
fi
- monitor_console=`awk '{print $NF}' $host_start | sed -n -e '1p'`
- serial_console=`awk '{print $NF}' $host_start | sed -n -e '2p'`
+ monitor_console=`awk '{print $5}' $host_start | sed -n -e '1p'`
+ serial_console=`awk '{print $5}' $host_start | sed -n -e '2p'`
QEMU_PID=`cat $pid_file`
echo "monitor console is $monitor_console"
echo "serial console is $serial_console"
@@ -272,7 +418,7 @@ check_guest_alive()
for i in 1 2 3 4 5 6 7 8 9
do
sleep 10
- ssh -i $host_key_priv -o StrictHostKeyChecking=no localhost -p 5555 echo "" > /dev/null 2>&1
+ ssh -i $host_key_priv -o StrictHostKeyChecking=no 127.0.0.1 -p 5555 echo "" > /dev/null 2>&1
if [ $? -eq 0 ]; then
return 0
else
@@ -285,8 +431,8 @@ check_guest_alive()
addr_translate()
{
#Get Guest physical address
- scp -o StrictHostKeyChecking=no -i $host_key_priv -P 5555 \
- localhost:$guest_tmp $HOST_DIR/guest_tmp > /dev/null 2>&1
+ scp -o StrictHostKeyChecking=no -i $host_key_priv -P 5555 \
+ 127.0.0.1:$guest_tmp $HOST_DIR/guest_tmp > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Failed to get Guest physical address, quit testing!"
kill -9 $QEMU_PID
@@ -301,29 +447,53 @@ addr_translate()
echo x-gpa2hva $GUEST_PHY > $monitor_console
cat $monitor_console > $monitor_console_output &
sleep 5
- HOST_VIRT=`awk '/qemu|QEMU/{next} {print $NF}' $monitor_console_output |cut -b 3-11`
+ if [ "$test_type" == "real" ]; then
+ HOST_VIRT=`awk '/x-gpa2hva|qemu|QEMU/{next} {print $NF}' $monitor_console_output`
+ elif [ "$test_type" == "spoof" ]; then
+ HOST_VIRT=`awk '/x-gpa2hva|qemu|QEMU/{next} {print $NF}' $monitor_console_output |cut -b 3-11`
+ fi
echo "Host virtual address is $HOST_VIRT"
#Get Host physical address
- ./page-types -p $QEMU_PID -LN -b anon | grep $HOST_VIRT > $host_tmp
+ if [ "$test_type" == "real" ]; then
+ victim -a vaddr=$HOST_VIRT,pid=$QEMU_PID > $host_tmp
+ elif [ "$test_type" == "spoof" ]; then
+ page-types -p $QEMU_PID -LN | grep $HOST_VIRT > $host_tmp
+ fi
sleep 5
- ADDR=`cat $host_tmp | awk '{print "0x"$2"000"}' `
+ if [ "$test_type" == "real" ]; then
+ ADDR=`cat $host_tmp | awk '{print $NF}'`
+ elif [ "$test_type" == "spoof" ]; then
+ ADDR=`cat $host_tmp | awk '{print "0x"$2"000"}' `
+ fi
echo "Host physical address is $ADDR"
}
error_inj()
{
- #Inject SRAO error
- cat $mce_inject_file > $mce_inject_data
- echo "ADDR $ADDR" >> $mce_inject_data
- echo "calling mce-inject $mce_inject_data"
- mce-inject $mce_inject_data
+ if [ "$test_type" == "real" ]; then
+ #Inject via APEI
+ echo "calling apei_inj $ADDR"
+ apei_inj $ADDR
+ sleep 1
+ touch $HOST_DIR/$trigger_file
+ echo "trigger" > $HOST_DIR/$trigger_file
+ scp -o StrictHostKeyChecking=no -i $host_key_priv -P 5555 $HOST_DIR/$trigger_file \
+ 127.0.0.1:$GUEST_DIR > /dev/null 2>&1
+ elif [ "$test_type" == "spoof" ]; then
+ #Inject via mce_inject
+ cat $mce_inject_file > $mce_inject_data
+ echo "ADDR $ADDR" >> $mce_inject_data
+ echo "calling mce-inject $mce_inject_data"
+ mce-inject $mce_inject_data
+ fi
+
}
get_guest_klog()
{
- cat $serial_console > $serial_console_output &
+ cat $serial_console > $serial_console_output &
}
check_guest_klog()
@@ -338,6 +508,22 @@ check_guest_klog()
}
+check_srar_lmce_log()
+{
+ ssh -i $host_key_priv -o StrictHostKeyChecking=no 127.0.0.1 -p 5555 \
+ "cat /var/log/mcelog" >> $serial_console_output
+ cat $serial_console_output | grep -q "SRAR"
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+ echo "SRAR error triggered successfully"
+ cat $serial_console_output | grep -q "LMCE"
+ if [ $? -eq 0 ]; then
+ echo "LMCE happens"
+ fi
+ return 0
+}
+
check_env
image_prepare
@@ -348,29 +534,36 @@ else
get_guest_klog
check_guest_alive
if [ $? -ne 0 ]; then
- echo 'Start Guest system failed, quit testing!'
+ echo 'Start Guest system failed, quit testing!'
else
sleep 5
- addr_translate
- error_inj
+ addr_translate
+ error_inj
sleep 5
- check_guest_klog
+ if [ "$test_type" == "real" ]; then
+ check_srar_lmce_log
+ elif [ "$test_type" == "spoof" ]; then
+ check_guest_klog
+ fi
if [ $? -ne 0 ]; then
- echo 'FAIL: Did not get expected log!'
- kill -9 $QEMU_PID
+ echo 'FAIL: Did not get expected log!'
+ kill -9 $QEMU_PID
exit 1
else
echo 'PASS: Inject error into guest!'
fi
- sleep 10
check_guest_alive
if [ $? -ne 0 ]; then
- echo 'FAIL: Guest System could have died!'
+ echo 'FAIL: Guest System could have died!'
else
echo 'PASS: Guest System alive!'
fi
fi
fi
-rm -f guest_tmp $host_start $monitor_console_output $serail_console_output $host_tmp $pid_file $mce_inject_data
-rm -f ./simple_process ./page-types
+rm -f guest_tmp $host_start $monitor_console_output $serial_console_output $host_tmp $pid_file
+if [ "$test_type" == "real" ]; then
+ rm -f $HOST_DIR/$trigger_file
+elif [ "$test_type" == "spoof" ]; then
+ rm -f $mce_inject_data
+fi
diff --git a/cases/function/kvm/patches/p2v.patch b/cases/function/kvm/patches/p2v.patch
deleted file mode 100644
index 328212b..0000000
--- a/cases/function/kvm/patches/p2v.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 0f28a71580205954313a8f1b592c97f49f330f32 Mon Sep 17 00:00:00 2001
-From: root <root@Romely.(none)>
-Date: Tue, 15 Mar 2011 11:03:13 -0400
-Subject: [PATCH 2/2] x-gpa2hva, translate guest physical address to host virtual address
-
-Add command x-gpa2hva to translate guest physical address to host
-virtual address. Because gpa to hva translation is not consistent, so
-this command is only used for debugging.
-
-The x-gpa2hva command provides one step in a chain of translations from
-guest virtual to guest physical to host virtual to host physical. Host
-physical is then used to inject a machine check error. As a
-consequence the HWPOISON code on the host and the MCE injection code
-in qemu-kvm are exercised.
-
-v3:
-
-- Rename to x-gpa2hva
-- Remove QMP support, because gpa2hva is not consistent
-
-v2:
-
-- Add QMP support
-
-Signed-off-by: Max Asbock <masbock@linux.vnet.ibm.com>
-Signed-off-by: Jiajia Zheng <jiajia.zheng@intel.com>
-Signed-off-by: Huang Ying <ying.huang@intel.com>
----
- hmp-commands.hx | 15 +++++++++++++++
- monitor.c | 22 ++++++++++++++++++++++
- 2 files changed, 37 insertions(+), 0 deletions(-)
-
-diff --git a/hmp-commands.hx b/hmp-commands.hx
-index 247fdf0..c7aaf1c 100644
---- a/hmp-commands.hx
-+++ b/hmp-commands.hx
-@@ -330,6 +330,21 @@ Start gdbserver session (default @var{port}=1234)
- ETEXI
-
- {
-+ .name = "x-gpa2hva",
-+ .args_type = "fmt:/,addr:l",
-+ .params = "/fmt addr",
-+ .help = "translate guest physical 'addr' to host virtual address, only for debugging",
-+ .user_print = do_gpa2hva_print,
-+ .mhandler.cmd_new = do_gpa2hva,
-+ },
-+
-+STEXI
-+@item x-gpa2hva @var{addr}
-+@findex x-gpa2hva
-+Translate guest physical @var{addr} to host virtual address, only for debugging.
-+ETEXI
-+
-+ {
- .name = "x",
- .args_type = "fmt:/,addr:l",
- .params = "/fmt addr",
-diff --git a/monitor.c b/monitor.c
-index fdbf9f3..f18aa2a 100644
---- a/monitor.c
-+++ b/monitor.c
-@@ -2749,6 +2749,28 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict)
- }
- #endif
-
-+static void do_gpa2hva_print(Monitor *mon, const QObject *data)
-+{
-+ QInt *qint;
-+
-+ qint = qobject_to_qint(data);
-+ monitor_printf(mon, "0x%lx\n", (unsigned long)qint->value);
-+}
-+
-+static int do_gpa2hva(Monitor *mon, const QDict *qdict, QObject **ret_data)
-+{
-+ target_phys_addr_t paddr;
-+ target_phys_addr_t size = TARGET_PAGE_SIZE;
-+ void *vaddr;
-+
-+ paddr = qdict_get_int(qdict, "addr");
-+ vaddr = cpu_physical_memory_map(paddr, &size, 0);
-+ cpu_physical_memory_unmap(vaddr, size, 0, 0);
-+ *ret_data = qobject_from_jsonf("%ld", (unsigned long)vaddr);
-+
-+ return 0;
-+}
-+
- static int do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data)
- {
- const char *fdname = qdict_get_str(qdict, "fdname");
---
-1.7.1
-
diff --git a/tools/simple_process/simple_process.c b/tools/simple_process/simple_process.c
index b6d3c4c..66f945f 100644
--- a/tools/simple_process/simple_process.c
+++ b/tools/simple_process/simple_process.c
@@ -5,14 +5,11 @@
int main(void)
{
- void *p = malloc(128);
- printf("allocating 128 bytes of memory\n");
- while (1)
- {
- memset(p, 0, 128);
- }
- return 0;
-}
-
-
+ void *p = malloc(0x100000);
+ printf("allocating 1M bytes of memory\n");
+ while (1) {
+ memset(p, 0, 0x100000);
+ }
+ return 0;
+}