tools/tests/x86_emulator/x86_emulate
tools/tests/x86_emulator/xop*.[ch]
tools/tests/xenstore/xs-test
-tools/tests/mce-test/tools/xen-mceinj
tools/tests/vpci/list.h
tools/tests/vpci/vpci.[hc]
tools/tests/vpci/test_vpci
xen-access
+xen-mceinj
xen-memshare
xen-ucode
xen-vmtrace
INSTALL_SBIN-$(CONFIG_X86) += xen-hvmcrash
INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx
INSTALL_SBIN-$(CONFIG_X86) += xen-lowmemd
+INSTALL_SBIN-$(CONFIG_X86) += xen-mceinj
INSTALL_SBIN-$(CONFIG_X86) += xen-memshare
INSTALL_SBIN-$(CONFIG_X86) += xen-mfndump
INSTALL_SBIN-$(CONFIG_X86) += xen-ucode
xen-vmtrace: xen-vmtrace.o
$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenforeignmemory) $(APPEND_LDFLAGS)
+xen-mceinj: xen-mceinj.o
+ $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS)
+
xenperf: xenperf.o
$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
--- /dev/null
+/*
+ * xen-mceinj.c: utilities to inject fake MCE for x86.
+ * Copyright (c) 2010, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Yunhong Jiang <yunhong.jiang@intel.com>
+ * Haicheng Li <haicheng.li@intel.com>
+ * Xudong Hao <xudong.hao@intel.com>
+ */
+
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+
+#define XC_WANT_COMPAT_MAP_FOREIGN_API
+#include <xenctrl.h>
+#include <xenguest.h>
+#include <inttypes.h>
+#include <sys/time.h>
+#include <xen/arch-x86/xen-mca.h>
+#include <xenstore.h>
+
+#define MCi_type_CTL 0x0
+#define MCi_type_STATUS 0x1
+#define MCi_type_ADDR 0x2
+#define MCi_type_MISC 0x3
+#define MCi_type_CTL2 0x4
+
+#define INVALID_MSR ~0UL
+
+/* Intel MSRs */
+#define MSR_IA32_MCG_CAP 0x00000179
+#define MSR_IA32_MCG_STATUS 0x0000017a
+#define MSR_IA32_MCG_CTL 0x0000017b
+#define MSR_IA32_MC0_CTL 0x00000400
+#define MSR_IA32_MC0_STATUS 0x00000401
+#define MSR_IA32_MC0_ADDR 0x00000402
+#define MSR_IA32_MC0_MISC 0x00000403
+#define MSR_IA32_MC0_CTL2 0x00000280
+
+#define MCG_STATUS_LMCE 0x8
+
+struct mce_info {
+ const char *description;
+ uint8_t mcg_stat;
+ unsigned int bank;
+ uint64_t mci_stat;
+ uint64_t mci_misc;
+ bool cmci;
+};
+
+static struct mce_info mce_table[] = {
+ /* LLC (Last Level Cache) EWB (Explicit Write Back) SRAO MCE */
+ {
+ .description = "MCE_SRAO_MEM",
+ .mcg_stat = 0x5,
+ .bank = 7,
+ .mci_stat = 0xBD2000008000017Aull,
+ .mci_misc = 0x86ull,
+ },
+ /* Memory Patrol Scrub SRAO MCE */
+ {
+ .description = "MCE_SRAO_LLC",
+ .mcg_stat = 0x5,
+ .bank = 8,
+ .mci_stat = 0xBD000000004000CFull,
+ .mci_misc = 0x86ull,
+ },
+ /* LLC EWB UCNA Error */
+ {
+ .description = "CMCI_UCNA_LLC",
+ .mcg_stat = 0x0,
+ .bank = 9,
+ .mci_stat = 0xBC20000080000136ull,
+ .mci_misc = 0x86ull,
+ .cmci = true,
+ },
+ /* AMD L1 instruction cache data or tag parity. */
+ {
+ .description = "AMD L1 icache parity",
+ .mcg_stat = 0x5,
+ .bank = 1,
+ .mci_stat = 0x9400000000000151ull,
+ .mci_misc = 0x86ull,
+ },
+ /* LLC (Last Level Cache) EWB (Explicit Write Back) SRAO MCE */
+ {
+ .description = "MCE_SRAO_MEM (Fatal)",
+ .mcg_stat = 0x5,
+ .bank = 7,
+ .mci_stat = 0xBF2000008000017Aull,
+ .mci_misc = 0x86ull,
+ },
+};
+#define MCE_TABLE_SIZE (sizeof(mce_table)/sizeof(mce_table[0]))
+
+#define LOGFILE stdout
+
+int dump;
+int lmce;
+struct xen_mc_msrinject msr_inj;
+
+static void Lprintf(const char *fmt, ...)
+{
+ char *buf;
+ va_list args;
+
+ va_start(args, fmt);
+ if (vasprintf(&buf, fmt, args) < 0)
+ abort();
+ fprintf(LOGFILE, "%s\n", buf);
+ va_end(args);
+ free(buf);
+}
+
+static void err(xc_interface *xc_handle, const char *fmt, ...)
+{
+ char *buf;
+ va_list args;
+
+ va_start(args, fmt);
+ if ( vasprintf(&buf, fmt, args) < 0 )
+ abort();
+ perror(buf);
+ va_end(args);
+ free(buf);
+
+ if ( xc_handle )
+ xc_interface_close(xc_handle);
+ exit(EXIT_FAILURE);
+}
+
+static void init_msr_inj(void)
+{
+ memset(&msr_inj, 0, sizeof(msr_inj));
+}
+
+static int flush_msr_inj(xc_interface *xc_handle)
+{
+ struct xen_mc mc;
+
+ mc.cmd = XEN_MC_msrinject;
+ mc.interface_version = XEN_MCA_INTERFACE_VERSION;
+ mc.u.mc_msrinject = msr_inj;
+
+ return xc_mca_op(xc_handle, &mc);
+}
+
+static unsigned int mca_cpuinfo(xc_interface *xc_handle)
+{
+ struct xen_mc mc;
+
+ memset(&mc, 0, sizeof(struct xen_mc));
+
+ mc.cmd = XEN_MC_physcpuinfo;
+ mc.interface_version = XEN_MCA_INTERFACE_VERSION;
+
+ if ( !xc_mca_op(xc_handle, &mc) )
+ return mc.u.mc_physcpuinfo.ncpus;
+ else
+ return 0;
+}
+
+static int inject_cmci(xc_interface *xc_handle, unsigned int cpu_nr)
+{
+ struct xen_mc mc;
+ unsigned int nr_cpus;
+
+ memset(&mc, 0, sizeof(struct xen_mc));
+
+ nr_cpus = mca_cpuinfo(xc_handle);
+ if ( !nr_cpus )
+ err(xc_handle, "Failed to get mca_cpuinfo");
+ if ( cpu_nr >= nr_cpus )
+ err(xc_handle, "-c %u is larger than %u", cpu_nr, nr_cpus - 1);
+
+ mc.cmd = XEN_MC_inject_v2;
+ mc.interface_version = XEN_MCA_INTERFACE_VERSION;
+
+ mc.u.mc_inject_v2.flags |= XEN_MC_INJECT_CPU_BROADCAST;
+ mc.u.mc_inject_v2.flags |= XEN_MC_INJECT_TYPE_CMCI;
+ mc.u.mc_inject_v2.cpumap.nr_bits = nr_cpus;
+
+ return xc_mca_op(xc_handle, &mc);
+}
+
+static int inject_mce(xc_interface *xc_handle, int cpu_nr)
+{
+ struct xen_mc mc;
+
+ memset(&mc, 0, sizeof(struct xen_mc));
+
+ mc.cmd = XEN_MC_mceinject;
+ mc.interface_version = XEN_MCA_INTERFACE_VERSION;
+ mc.u.mc_mceinject.mceinj_cpunr = cpu_nr;
+
+ return xc_mca_op(xc_handle, &mc);
+}
+
+static int inject_lmce(xc_interface *xc_handle, unsigned int cpu)
+{
+ uint8_t *cpumap = NULL;
+ size_t cpumap_size, line, shift;
+ unsigned int nr_cpus;
+ int ret;
+
+ nr_cpus = mca_cpuinfo(xc_handle);
+ if ( !nr_cpus )
+ err(xc_handle, "Failed to get mca_cpuinfo");
+ if ( cpu >= nr_cpus )
+ err(xc_handle, "-c %u is larger than %u", cpu, nr_cpus - 1);
+
+ cpumap_size = (nr_cpus + 7) / 8;
+ cpumap = malloc(cpumap_size);
+ if ( !cpumap )
+ err(xc_handle, "Failed to allocate cpumap\n");
+ memset(cpumap, 0, cpumap_size);
+ line = cpu / 8;
+ shift = cpu % 8;
+ memset(cpumap + line, 1 << shift, 1);
+
+ ret = xc_mca_op_inject_v2(xc_handle, XEN_MC_INJECT_TYPE_LMCE,
+ cpumap, cpumap_size * 8);
+
+ free(cpumap);
+ return ret;
+}
+
+static uint64_t bank_addr(int bank, int type)
+{
+ uint64_t addr;
+
+ switch ( type )
+ {
+ case MCi_type_CTL:
+ case MCi_type_STATUS:
+ case MCi_type_ADDR:
+ case MCi_type_MISC:
+ addr = MSR_IA32_MC0_CTL + (bank * 4) + type;
+ break;
+ case MCi_type_CTL2:
+ addr = MSR_IA32_MC0_CTL2 + bank;
+ break;
+ default:
+ addr = INVALID_MSR;
+ break;
+ }
+
+ return addr;
+}
+
+static int add_msr_intpose(xc_interface *xc_handle,
+ uint32_t cpu_nr,
+ uint32_t flags,
+ uint64_t msr,
+ uint64_t val,
+ domid_t domid)
+{
+ uint32_t count;
+
+ if ( (msr_inj.mcinj_count &&
+ (cpu_nr != msr_inj.mcinj_cpunr || flags != msr_inj.mcinj_flags ||
+ domid != msr_inj.mcinj_domid)) ||
+ msr_inj.mcinj_count == MC_MSRINJ_MAXMSRS )
+ {
+ flush_msr_inj(xc_handle);
+ init_msr_inj();
+ }
+ count = msr_inj.mcinj_count;
+
+ if ( !count )
+ {
+ msr_inj.mcinj_cpunr = cpu_nr;
+ msr_inj.mcinj_flags = flags;
+ msr_inj.mcinj_domid = domid;
+ }
+ msr_inj.mcinj_msr[count].reg = msr;
+ msr_inj.mcinj_msr[count].value = val;
+ msr_inj.mcinj_count++;
+
+ return 0;
+}
+
+static int add_msr_bank_intpose(xc_interface *xc_handle,
+ uint32_t cpu_nr,
+ uint32_t flags,
+ uint32_t type,
+ uint32_t bank,
+ uint64_t val,
+ domid_t domid)
+{
+ uint64_t msr;
+
+ msr = bank_addr(bank, type);
+ if ( msr == INVALID_MSR )
+ return -1;
+ return add_msr_intpose(xc_handle, cpu_nr, flags, msr, val, domid);
+}
+
+static int inject_mcg_status(xc_interface *xc_handle,
+ uint32_t cpu_nr,
+ uint64_t val,
+ domid_t domid)
+{
+ return add_msr_intpose(xc_handle, cpu_nr, MC_MSRINJ_F_INTERPOSE,
+ MSR_IA32_MCG_STATUS, val, domid);
+}
+
+static int inject_mci_status(xc_interface *xc_handle,
+ uint32_t cpu_nr,
+ uint64_t bank,
+ uint64_t val,
+ domid_t domid)
+{
+ return add_msr_bank_intpose(xc_handle, cpu_nr, MC_MSRINJ_F_INTERPOSE,
+ MCi_type_STATUS, bank, val, domid);
+}
+
+static int inject_mci_misc(xc_interface *xc_handle,
+ uint32_t cpu_nr,
+ uint64_t bank,
+ uint64_t val,
+ domid_t domid)
+{
+ return add_msr_bank_intpose(xc_handle, cpu_nr, MC_MSRINJ_F_INTERPOSE,
+ MCi_type_MISC, bank, val, domid);
+}
+
+static int inject_mci_addr(xc_interface *xc_handle,
+ uint32_t cpu_nr,
+ uint64_t bank,
+ uint64_t val,
+ domid_t domid)
+{
+ return add_msr_bank_intpose(xc_handle, cpu_nr,
+ MC_MSRINJ_F_INTERPOSE |
+ ((domid >= DOMID_FIRST_RESERVED &&
+ domid != DOMID_SELF) ?
+ 0 : MC_MSRINJ_F_GPADDR),
+ MCi_type_ADDR, bank, val, domid);
+}
+
+static int inject(xc_interface *xc_handle, struct mce_info *mce,
+ uint32_t cpu_nr, uint32_t domain, uint64_t gaddr)
+{
+ int ret = 0;
+ uint8_t mcg_status = mce->mcg_stat;
+
+ if ( lmce )
+ {
+ if ( mce->cmci )
+ err(xc_handle, "No support to inject CMCI as LMCE");
+ mcg_status |= MCG_STATUS_LMCE;
+ }
+ ret = inject_mcg_status(xc_handle, cpu_nr, mcg_status, domain);
+ if ( ret )
+ err(xc_handle, "Failed to inject MCG_STATUS MSR");
+
+ ret = inject_mci_status(xc_handle, cpu_nr,
+ mce->bank, mce->mci_stat, domain);
+ if ( ret )
+ err(xc_handle, "Failed to inject MCi_STATUS MSR");
+
+ ret = inject_mci_misc(xc_handle, cpu_nr,
+ mce->bank, mce->mci_misc, domain);
+ if ( ret )
+ err(xc_handle, "Failed to inject MCi_MISC MSR");
+
+ ret = inject_mci_addr(xc_handle, cpu_nr, mce->bank, gaddr, domain);
+ if ( ret )
+ err(xc_handle, "Failed to inject MCi_ADDR MSR");
+
+ ret = flush_msr_inj(xc_handle);
+ if ( ret )
+ err(xc_handle, "Failed to inject MSR");
+ if ( mce->cmci )
+ ret = inject_cmci(xc_handle, cpu_nr);
+ else if ( lmce )
+ ret = inject_lmce(xc_handle, cpu_nr);
+ else
+ ret = inject_mce(xc_handle, cpu_nr);
+ if ( ret )
+ err(xc_handle, "Failed to inject MCE error");
+
+ return 0;
+}
+
+static long xs_get_dom_mem(int domid)
+{
+ char path[128];
+ char *memstr;
+ uint64_t mem;
+ unsigned int plen;
+ struct xs_handle *xs;
+
+ xs = xs_open(0);
+ if (!xs)
+ return -1;
+
+ sprintf(path, "/local/domain/%d/memory/target", domid);
+ memstr = xs_read(xs, XBT_NULL, path, &plen);
+ xs_close(xs);
+
+ if (!memstr || !plen)
+ return -1;
+
+ mem = atoll(memstr) * 1024;
+ free(memstr);
+
+ return mem;
+}
+
+static struct option opts[] = {
+ {"cpu", 0, 0, 'c'},
+ {"domain", 0, 0, 'd'},
+ {"dump", 0, 0, 'D'},
+ {"help", 0, 0, 'h'},
+ {"page", 0, 0, 'p'},
+ {"lmce", 0, 0, 'l'},
+ {"", 0, 0, '\0'}
+};
+
+static void help(void)
+{
+ unsigned int i;
+
+ printf("Usage: xen-mceinj [OPTION]...\n"
+ "\n"
+ "Mandatory arguments to long options are mandatory"
+ "for short options too.\n"
+ " -D, --dump dump addr info without error injection\n"
+ " -c, --cpu=CPU target CPU\n"
+ " -d, --domain=DOMID target domain, the default is Xen itself\n"
+ " -h, --help print this page\n"
+ " -p, --page=ADDR physical address to report\n"
+ " -l, --lmce inject as LMCE (Intel only)\n"
+ " -t, --type=ERROR error type\n");
+
+ for ( i = 0; i < MCE_TABLE_SIZE; i++ )
+ printf(" %2d : %s\n",
+ i, mce_table[i].description);
+}
+
+int main(int argc, char *argv[])
+{
+ int type = 0;
+ int c, opt_index;
+ uint32_t domid;
+ xc_interface *xc_handle;
+ unsigned int cpu_nr;
+ uint64_t gaddr, max_gpa;
+
+ /* Default Value */
+ domid = DOMID_XEN;
+ gaddr = 0x180020;
+ cpu_nr = 0;
+
+ init_msr_inj();
+ xc_handle = xc_interface_open(NULL, NULL, 0);
+ if ( !xc_handle )
+ {
+ Lprintf("Failed to get xc interface");
+ exit(EXIT_FAILURE);
+ }
+
+ while ( 1 )
+ {
+ c = getopt_long(argc, argv, "c:Dd:t:hp:l", opts, &opt_index);
+ if ( c == -1 )
+ break;
+ switch ( c )
+ {
+ case 'D':
+ dump=1;
+ break;
+ case 'c':
+ cpu_nr = strtoul(optarg, &optarg, 10);
+ if ( strlen(optarg) != 0 )
+ err(xc_handle, "Please input a digit parameter for CPU");
+ break;
+ case 'd':
+ domid = strtol(optarg, &optarg, 10);
+ if ( strlen(optarg) != 0 )
+ err(xc_handle, "Please input a digit parameter for domain");
+ break;
+ case 'p':
+ gaddr = strtol(optarg, &optarg, 0);
+ if ( strlen(optarg) != 0 )
+ err(xc_handle, "Please input correct page address");
+ break;
+ case 't':
+ type = strtol(optarg, NULL, 0);
+ break;
+ case 'l':
+ lmce = 1;
+ break;
+ case 'h':
+ default:
+ help();
+ return 0;
+ }
+ }
+
+ if ( domid != DOMID_XEN )
+ {
+ max_gpa = xs_get_dom_mem(domid);
+ Lprintf("get domain %d max gpa is: 0x%lx", domid, max_gpa);
+ if ( gaddr >= max_gpa )
+ err(xc_handle, "Fail: gaddr exceeds max_gpa 0x%lx", max_gpa);
+ }
+ Lprintf("get gaddr of error inject is: 0x%lx", gaddr);
+
+ if ( dump )
+ {
+ if ( domid == DOMID_XEN )
+ Lprintf("Xen: gaddr=0x%lx", gaddr);
+ else
+ Lprintf("Dom%d: gaddr=0x%lx", domid, gaddr);
+ goto out;
+ }
+
+ if ( type < 0 || type >= MCE_TABLE_SIZE )
+ {
+ err(xc_handle, "Unsupported error type");
+ goto out;
+ }
+
+ inject(xc_handle, &mce_table[type], cpu_nr, domid, gaddr);
+
+ out:
+ xc_interface_close(xc_handle);
+ return 0;
+}
SUBDIRS-y :=
SUBDIRS-y += resource
SUBDIRS-$(CONFIG_X86) += cpu-policy
-SUBDIRS-$(CONFIG_X86) += mce-test
SUBDIRS-$(CONFIG_X86) += tsx
ifneq ($(clang),y)
SUBDIRS-$(CONFIG_X86) += x86_emulator
+++ /dev/null
-.PHONY: all clean distclean
-
-all:
- $(MAKE) -C tools
-
-clean:
- $(MAKE) -C tools clean
-
-distclean:
- $(MAKE) -C tools distclean
-
-install uninstall:
+++ /dev/null
-Xen MCE test suite
----------------
-
-The Xen MCE test suite is a collection of tools and test scripts for
-testing the Xen MCE processing features. The goal is to cover
-most Xen MCE processing code paths and features with automation tests.
-
-
-In the Package
---------------
-
-Here is a short description of what is included in the package
-
-README
- This is document
-
-Makefile
- For compile
-
-cases/*
- Contains all test cases, which may be organized in sub-directories,
- the interface of test case is a shell script under cases/, such as:
- -- cases/srao_mem/dom0/cases.sh
-
-config/*
- Contains test configuration files, which specifies the parameters
- for test cases, etc.
-
-lib/*
- Contains some shell scripts, in which some common shell
- functions and variable definitions are defined to be used by
- test cases.
-
-tools/*
- Tools used by MCE test suites, now only xen-mceinj tool.
-
-results/
- When test is done, the test result will be placed in this
- directory, test results of various cases may be in corresponding
- directory.
- For example, files in
- results/srao_mem_dom0/result
- is the result for test case cases/srao_mem/dom0/cases.sh, there will
- be 3 result conditions: PASSED/FAILED/NORESULT.
- results/<test_case>/testlog #the test log during testing
- results/<test_case>/mcelog #mcelog output during testing
- results/<test_case>/xenlog #Xen log during testing
- results/<test_case>/gklog #VM guest kernel log during testing
- results/<test_case>/guest_config #config file used to create guest
-
-
-Test Instruction
-----------------
-
-1. make sure you have a dom0 with mce support
- CONFIG_X86_MCE=y
- CONFIG_X86_MCE_INTEL=y
- CONFIG_X86_MCE_AMD=y
- CONFIG_X86_MCE_THRESHOLD=y
- CONFIG_X86_MCE_INJECT=y
-
-2. run system at xen and start xend. A installed guest image is
- necessary when do guest MCE error injection.
-3. compile tools that used to test. in mce-test, $make.
- Note: make sure compile xen/tools before do this step
-4. run test cases that you want.
- e.g. $sh cases/srao_mem/dom0/cases.sh -d 0 -p 0x0200 -c 2 -t 1
-5. get test result in results directory
-
-
-Notes
-----------------
-All test cases fake a error and inject this error in 0x180020, For Xen
-test cases(e.g. cases/srao_mem/xen/cases.sh), error happen on every page
-may cause a Xen panic.
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=srao_llc_dom0
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the optional options================"
- echo -e "\t-d domainID\t: 0"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-while getopts ":c:d:p:h" option
-do
- case "$option" in
- c) injcpu=$OPTARG;;
- d) domid=$OPTARG;;
- p) pageaddr=$OPTARG;;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-[ -z $domid ] && domid=0
-
-inject()
-{
- mce_inject_trigger $MCE_SRAO_LLC -d $domid -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- inject || ret_val=1
- xen_verify || ret_val=1
- mcelog_verify $MCE_SRAO_LLC || ret_val=1
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=srao_llc_guest
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the must have options==============="
- echo -e "\t-i image\t: guest image"
- echo -e "\t-m memory\t: set guest virtual memory"
- echo "======== ========"
- echo "================Below are the optional options================"
- echo -e "\t-u vcpus\t: set guest virtual cpus number"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-[ $# -lt 1 ] && usage
-
-while getopts ":i:u:m:c:p:hl:" option
-do
- case "$option" in
- i) image=$OPTARG; offset=`kpartx -l $image | awk '{print $NF*512}'`;;
- u) vcpus=$OPTARG;;
- m) memory=$OPTARG;;
- c) injcpu=$OPTARG;;
- p) pageaddr=$OPTARG;;
- l) early_kill="0";;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-
-start_guest()
-{
- create_hvm_guest $image -u $vcpus -m $memory
- if [ $? -ne 0 ]; then
- echo " Create guest fail!"
- return 1
- fi
- return 0
-}
-
-inject()
-{
- mce_inject_trigger $MCE_SRAO_LLC -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- start_guest || ret_val=1
- inject || ret_val=1
- xen_verify || ret_val=1
- guest_verify || ret_val=1
- mcelog_verify $MCE_SRAO_LLC || ret_val=1
- des_guest
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=srao_llc_xen
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the optional options================"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-while getopts ":c:p:h" option
-do
- case "$option" in
- c) injcpu=$OPTARG;;
- p) pageaddr=$OPTARG;;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-inject()
-{
- mce_inject_trigger $MCE_SRAO_LLC -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- inject || ret_val=1
- xen_verify || ret_val=1
- mcelog_verify $MCE_SRAO_LLC || ret_val=1
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=srao_mem_dom0
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the optional options================"
- echo -e "\t-d domainID\t: 0"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-while getopts ":c:d:p:h" option
-do
- case "$option" in
- c) injcpu=$OPTARG;;
- d) domid=$OPTARG;;
- p) pageaddr=$OPTARG;;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-[ -z $domid ] && domid=0
-
-inject()
-{
- mce_inject_trigger $MCE_SRAO_MEM -d $domid -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- inject || ret_val=1
- xen_verify || ret_val=1
- mcelog_verify $MCE_SRAO_MEM || ret_val=1
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=srao_mem_guest
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the must have options==============="
- echo -e "\t-i image\t: guest image"
- echo -e "\t-m memory\t: set guest virtual memory"
- echo "======== ========"
- echo "================Below are the optional options================"
- echo -e "\t-u vcpus\t: set guest virtual cpus number"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-[ $# -lt 1 ] && usage
-
-while getopts ":i:u:m:c:p:hl:" option
-do
- case "$option" in
- i) image=$OPTARG; offset=`kpartx -l $image | awk '{print $NF*512}'`;;
- u) vcpus=$OPTARG;;
- m) memory=$OPTARG;;
- c) injcpu=$OPTARG;;
- p) pageaddr=$OPTARG;;
- l) early_kill="0";;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-
-start_guest()
-{
- create_hvm_guest $image -u $vcpus -m $memory
- if [ $? -ne 0 ]; then
- echo " Create guest fail!"
- return 1
- fi
- return 0
-}
-
-inject()
-{
- mce_inject_trigger $MCE_SRAO_MEM -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- start_guest || ret_val=1
- inject || ret_val=1
- xen_verify || ret_val=1
- guest_verify || ret_val=1
- mcelog_verify $MCE_SRAO_MEM || ret_val=1
- des_guest
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=srao_mem_xen
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the optional options================"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-while getopts ":c:p:h" option
-do
- case "$option" in
- c) injcpu=$OPTARG;;
- p) pageaddr=$OPTARG;;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-inject()
-{
- mce_inject_trigger $MCE_SRAO_MEM -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- inject || ret_val=1
- xen_verify || ret_val=1
- mcelog_verify $MCE_SRAO_MEM || ret_val=1
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=ucna_llc_dom0
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the optional options================"
- echo -e "\t-d domainID\t: 0"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-while getopts ":c:d:p:h" option
-do
- case "$option" in
- c) injcpu=$OPTARG;;
- d) domid=$OPTARG;;
- p) pageaddr=$OPTARG;;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-[ -z $domid ] && domid=0
-
-inject()
-{
- mce_inject_trigger $CMCI_UCNA_LLC -d $domid -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- inject || ret_val=1
- mcelog_verify $CMCI_UCNA_LLC || ret_val=1
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=ucna_llc_guest
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the must have options==============="
- echo -e "\t-i image\t: guest image"
- echo -e "\t-m memory\t: set guest virtual memory"
- echo "======== ========"
- echo "================Below are the optional options================"
- echo -e "\t-u vcpus\t: set guest virtual cpus number"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-[ $# -lt 1 ] && usage
-
-while getopts ":i:u:m:c:p:hl:" option
-do
- case "$option" in
- i) image=$OPTARG; offset=`kpartx -l $image | awk '{print $NF*512}'`;;
- u) vcpus=$OPTARG;;
- m) memory=$OPTARG;;
- c) injcpu=$OPTARG;;
- p) pageaddr=$OPTARG;;
- l) early_kill="0";;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-
-start_guest()
-{
- create_hvm_guest $image -u $vcpus -m $memory
- if [ $? -ne 0 ]; then
- echo " Create guest fail!"
- return 1
- fi
- return 0
-}
-
-inject()
-{
- mce_inject_trigger $CMCI_UCNA_LLC -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- start_guest || ret_val=1
- inject || ret_val=1
- mcelog_verify $CMCI_UCNA_LLC || ret_val=1
- des_guest
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-sd=$(dirname $0)
-export ROOT=`(cd $sd/../../../; pwd)`
-export this_case=ucna_llc_xen
-
-. $ROOT/lib/xen-mceinj-tool.sh
-
-usage()
-{
- echo "Usage: ./cases.sh [-options] [arguments]"
- echo "================Below are the optional options================"
- echo -e "\t-c injcpu\t: which cpu to inject error"
- echo -e "\t-p pageaddr\t: Guest Physical Address to inject error"
- echo -e "\t\t\tBy default, the GPA is 0x180020"
- echo -e "\t-h help"
- exit 0
-}
-
-while getopts ":c:p:h" option
-do
- case "$option" in
- c) injcpu=$OPTARG;;
- p) pageaddr=$OPTARG;;
- h) usage;;
- *) echo "invalid option!"; usage;;
- esac
-done
-
-inject()
-{
- mce_inject_trigger $CMCI_UCNA_LLC -u $injcpu -p $pageaddr
- if [ $? -eq 0 ]; then
- show " Passed: Successfully to fake and inject a MCE error"
- else
- show " Failed: Fake error and inject fail !!"
- return 1
- fi
- return 0
-}
-
-do_main()
-{
- ret_val=0
- clean_env
- inject || ret_val=1
- mcelog_verify $CMCI_UCNA_LLC || ret_val=1
- gen_result $ret_val
-}
-
-do_main "$@"
+++ /dev/null
-#!/bin/bash
-#
-# Software injection based test cases: test cases are triggered via
-# mce-inject tool.
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-export MCE_SRAO_MEM=0
-export MCE_SRAO_LLC=1
-export CMCI_UCNA_LLC=2
+++ /dev/null
-#!/bin/bash
-#
-# Software injection based test cases: test cases are triggered via
-# mce-inject tool.
-# Copyright (c) 2010, Intel Corporation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License version
-# 2 as published by the Free Software Foundation.
-#
-# 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 have received a copy of the GNU General Public License
-# along with this program; If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Xudong Hao <xudong.hao@intel.com>
-#
-
-. $ROOT/config/setup.conf
-
-#Guest Image Preparation
-hvm_image_prepare()
-{
- local image=$1
- local tmpdir=`mktemp -d`
- local tmpfile=`mktemp`
- local offset=`kpartx -l $image | awk '{print $NF*512}'`
- mount -oloop,offset=$offset $image $tmpdir && echo "mount image to $tmpdir"
- local g_grub=$tmpdir/boot/grub/grub.conf
- if [ $? -ne 0 ]; then
- show " Mount image failed!"
- return 1
- fi
-
- if ! grep FLAG_CONSOLE $g_grub; then
- sed -e '/kernel/s/$/ console=ttyS0,115200,8n1 console=tty0/g' \
- $g_grub > $tmpfile
- mv -f $tmpfile $g_grub
- rm -f $tmpfile
- echo "
-#### FLAG_CONSOLE #### " >> $g_grub
- fi
- umount $tmpdir
- rm -fr $tmpdir
-
- return 0
-}
-
-create_hvm_guest()
-{
- local image=$1
- local originconfig="/etc/xen/xmexample.hvm"
- local TF=`mktemp`
- local case_dir=$ROOT/results/$this_case
- local config=$case_dir/guest_config
- [ -d $case_dir ] || mkdir $case_dir
- [ -f $logfile ] || touch $logfile
- local File=`echo $image|sed "s/\//\\\\\\\\\\//g"`
- local g_name="`basename $image`_`date +%H%M%S`"
-
- hvm_image_prepare $image
-
- while getopts ":u:m:" Option
- do
- case $Option in
- u ) vcpus=$OPTARG;;
- m ) memory=$OPTARG;;
- e ) bridge_name=$OPTARG;;
- * ) ;;
- esac
- done
-
- cp $originconfig $config -f
-
- if [ -z $image ]; then
- show "Image file $image does not exist, Please input one valid file"
- return 1
- fi
-
- sed -e "/^disk/s/file:.*,\(hda\)/file:${File},\1/" $config \
- | sed -e "/^disk/s/phy:.*,\(hda\)/file:${File},\1/" >$TF
- mv -f $TF $config
-
- [ -z $memory ] || sed -i "/^memory/s/^.*$/memory = $memory/" $config
- [ -z $vcpus ] || sed -i "1,/^#vcpus/s/^#vcpus.*$/vcpus=$vcpus/;1d" $config
- sed -i "/^vif/s/vif/#vif/" $config
- sed -i "/^name/s/^.*$/name = \"$g_name\"/" $config
-
- string1=$(ls /dev/pts | sort)
- xm cr $config
- [ $? -eq 0 ] && domid=`xm list $g_name | tail -n1 | awk '{print $2}'`
- if [ -z $domid ]; then
- show " Guest can not boot up"
- return 1
- fi
-
- sleep 10
-
- string2=$(ls /dev/pts | sort)
-
- get_guest_klog
- sleep 40
-
- return 0
-}
-
-get_guest_klog()
-{
- local case_dir=$ROOT/results/$this_case
- gklog=$case_dir/gklog
- [ -d $case_dir ] || mkdir $case_dir
- [ -f $gklog ] || touch $gklog
- for fo in $string2; do
- echo $string1 | grep $fo -wq
- [ $? -eq 1 ] && num=$fo
- done
- cat /dev/pts/$num > $gklog &
-}
-
-mce_inject_trigger()
-{
- local errtype=$1
- local append=""
- while getopts ":d:u:p:" Option
- do
- case $Option in
- d ) domid=$OPTARG;;
- u ) cpu=$OPTARG;;
- p ) pageaddr=$OPTARG;;
- * ) ;;
- esac
- done
-
- [ -z $domid ] || append=$append" -d $domid"
- [ -z $cpu ] || append=$append" -c $cpu"
- [ -z $pageaddr ] || append=$append" -p $pageaddr"
-
- [ -f $ROOT/tools/xen-mceinj ]
- if [ $? -eq 0 ]; then
- xm dmesg -c
- $ROOT/tools/xen-mceinj -t $errtype $append
- if [ $? -ne 0 ]; then
- show " Failed: Maybe the memory addr is out of range. \
- Please check whether used xen-mceinj tool correctlly"
- return 1
- fi
- else
- show " Failed: please compile xen-mce inject tool firstly"
- return 1
- fi
- return 0
-}
-
-xen_verify()
-{
- local case_dir=$ROOT/results/$this_case
- local xenlog=$case_dir/xenlog
- [ -d $case_dir ] || mkdir $case_dir
- [ -f $xenlog ] || touch $xenlog
- xm dmesg > $xenlog
- grep "Error is successfully recovered" $xenlog > /dev/null
- if [ $? -eq 0 ]; then
- show " Passed: Xen handle this MCE error successfully"
- else
- show " Failed: Xen does not handle MCE error correctly !!"
- return 1
- fi
- return 0
-}
-
-guest_verify()
-{
- grep "kernel page recovery" $gklog > /dev/null
- if [ $? -eq 0 ]; then
- show " Passed: Guest recive MCE error and solved correctly"
- else
- show " Failed: Guest fail to solve MCE error"
- return 1
- fi
- return 0
-}
-
-mcelog_verify()
-{
- local err_type=$1
- local ret=0
- local case_dir=$ROOT/results/$this_case
- local mcelog=$case_dir/mcelog
- [ -d $case_dir ] || mkdir $case_dir
- [ -f $mcelog ] || touch $mcelog
- mcelog > $mcelog
- if [ -z $mcelog ]; then
- show " Failed: MCELOG does not catch anything"
- return 1
- else
- if [ $err_type -eq 0 ]; then
- grep "MEMORY CONTROLLER MS_CHANNELunspecified_ERR" $mcelog \
- > /dev/null
- ret=$?
- elif [ $err_type -eq 1 ]; then
- grep "Generic CACHE Level-2 Eviction Error" $mcelog > /dev/null
- ret=$?
- elif [ $err_type -eq 2 ]; then
- grep "Data CACHE Level-2 Data-Read Error" $mcelog > /dev/null
- ret=$?
- fi
-
- if [ $ret -eq 0 ]; then
- show " Passed: MCElog catch a correct error"
- else
- show " Failed: MCE log catch a incorrect error !!"
- return 1
- fi
- fi
-
- return 0
-}
-
-function des_guest()
-{
- xm des $domid
-}
-
-function clean_env()
-{
- [ -d $ROOT/results ] || mkdir $ROOT/results
- # clean logs and results of last test for this case
- rm -fr $ROOT/results/$this_case/*
-}
-
-function show()
-{
- local case_dir=$ROOT/results/$this_case
- local logfile=$case_dir/testlog
- [ -d $case_dir ] || mkdir $case_dir
- [ -f $logfile ] || touch $logfile
- echo -e $* | tee -a $logfile > /dev/null
-}
-
-function gen_result()
-{
- local ret=$1
- local case_dir=$ROOT/results/$this_case
- local result=$case_dir/result
- [ -d $case_dir ] || mkdir $case_dir
- [ -f $result ] || touch $result
-
- if [ $ret -eq 0 ]; then
- echo "PASSED" > $result
- elif [ $ret -eq 1 ]; then
- echo "FAILED" > $result
- echo " Please check testlog for details!!! " >> $result
- else
- echo "NORESULT" > $result
- echo " Please check testlog for details!!! " >> $result
- fi
-}
+++ /dev/null
-XEN_ROOT=$(CURDIR)/../../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-CFLAGS += -Werror
-CFLAGS += $(CFLAGS_libxenctrl)
-CFLAGS += $(CFLAGS_libxenguest)
-CFLAGS += $(CFLAGS_libxenstore)
-CFLAGS += $(CFLAGS_xeninclude)
-
-.PHONY: all
-all: xen-mceinj
-
-install: xen-mceinj
- $(INSTALL_PROG) xen-mceinj $(DESTDIR)$(sbindir)
-
-.PHONY: clean
-clean:
- $(RM) *.o xen-mceinj
-
-.PHONY: distclean
-distclean: clean
-
-xen-mceinj: xen-mceinj.o Makefile
- $(CC) -o $@ $< $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore)
+++ /dev/null
-Xen Machine Check Exception(MCE) error inject tool
-----------------------------------------------
-
-xen-mceinj is a software MCE injection tool, which is based on Xen
-MCE injection mechanism. It allows to inject machine check errors on the
-software level into a running Xen/dom0/VM. This is intended for
-validation of the Xen machine check handler.
-
-With the help of the Makefile, it is possible to compile a binary file
-named "xen-mceinj".
-
-Usage
------
-$make (make install) --Note: make sure compile xen/tools before do this step
-$./xen-mceinj [OPTION]...
-
-OPTION arguments can be:
- -D, --dump dump addr info without error injection
- -c, --cpu=CPU_ID target CPU, the default is CPU0
- -d, --domain=DomID target domain, the default is Xen itself
- -p, --page physical page address, the default is 0x180020
- -t, --type=error error type
-
-For detail help, please refer to "./xen-mceinj -h"
+++ /dev/null
-/*
- * xen-mceinj.c: utilities to inject fake MCE for x86.
- * Copyright (c) 2010, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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 have received a copy of the GNU General Public License along with
- * this program; If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Yunhong Jiang <yunhong.jiang@intel.com>
- * Haicheng Li <haicheng.li@intel.com>
- * Xudong Hao <xudong.hao@intel.com>
- */
-
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <getopt.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdarg.h>
-
-#define XC_WANT_COMPAT_MAP_FOREIGN_API
-#include <xenctrl.h>
-#include <xenguest.h>
-#include <inttypes.h>
-#include <sys/time.h>
-#include <xen/arch-x86/xen-mca.h>
-#include <xenstore.h>
-
-#define MCi_type_CTL 0x0
-#define MCi_type_STATUS 0x1
-#define MCi_type_ADDR 0x2
-#define MCi_type_MISC 0x3
-#define MCi_type_CTL2 0x4
-
-#define INVALID_MSR ~0UL
-
-/* Intel MSRs */
-#define MSR_IA32_MCG_CAP 0x00000179
-#define MSR_IA32_MCG_STATUS 0x0000017a
-#define MSR_IA32_MCG_CTL 0x0000017b
-#define MSR_IA32_MC0_CTL 0x00000400
-#define MSR_IA32_MC0_STATUS 0x00000401
-#define MSR_IA32_MC0_ADDR 0x00000402
-#define MSR_IA32_MC0_MISC 0x00000403
-#define MSR_IA32_MC0_CTL2 0x00000280
-
-#define MCG_STATUS_LMCE 0x8
-
-struct mce_info {
- const char *description;
- uint8_t mcg_stat;
- unsigned int bank;
- uint64_t mci_stat;
- uint64_t mci_misc;
- bool cmci;
-};
-
-static struct mce_info mce_table[] = {
- /* LLC (Last Level Cache) EWB (Explicit Write Back) SRAO MCE */
- {
- .description = "MCE_SRAO_MEM",
- .mcg_stat = 0x5,
- .bank = 7,
- .mci_stat = 0xBD2000008000017Aull,
- .mci_misc = 0x86ull,
- },
- /* Memory Patrol Scrub SRAO MCE */
- {
- .description = "MCE_SRAO_LLC",
- .mcg_stat = 0x5,
- .bank = 8,
- .mci_stat = 0xBD000000004000CFull,
- .mci_misc = 0x86ull,
- },
- /* LLC EWB UCNA Error */
- {
- .description = "CMCI_UCNA_LLC",
- .mcg_stat = 0x0,
- .bank = 9,
- .mci_stat = 0xBC20000080000136ull,
- .mci_misc = 0x86ull,
- .cmci = true,
- },
- /* AMD L1 instruction cache data or tag parity. */
- {
- .description = "AMD L1 icache parity",
- .mcg_stat = 0x5,
- .bank = 1,
- .mci_stat = 0x9400000000000151ull,
- .mci_misc = 0x86ull,
- },
- /* LLC (Last Level Cache) EWB (Explicit Write Back) SRAO MCE */
- {
- .description = "MCE_SRAO_MEM (Fatal)",
- .mcg_stat = 0x5,
- .bank = 7,
- .mci_stat = 0xBF2000008000017Aull,
- .mci_misc = 0x86ull,
- },
-};
-#define MCE_TABLE_SIZE (sizeof(mce_table)/sizeof(mce_table[0]))
-
-#define LOGFILE stdout
-
-int dump;
-int lmce;
-struct xen_mc_msrinject msr_inj;
-
-static void Lprintf(const char *fmt, ...)
-{
- char *buf;
- va_list args;
-
- va_start(args, fmt);
- if (vasprintf(&buf, fmt, args) < 0)
- abort();
- fprintf(LOGFILE, "%s\n", buf);
- va_end(args);
- free(buf);
-}
-
-static void err(xc_interface *xc_handle, const char *fmt, ...)
-{
- char *buf;
- va_list args;
-
- va_start(args, fmt);
- if (vasprintf(&buf, fmt, args) < 0)
- abort();
- perror(buf);
- va_end(args);
- free(buf);
-
- if ( xc_handle )
- xc_interface_close(xc_handle);
- exit(EXIT_FAILURE);
-}
-
-static void init_msr_inj(void)
-{
- memset(&msr_inj, 0, sizeof(msr_inj));
-}
-
-static int flush_msr_inj(xc_interface *xc_handle)
-{
- struct xen_mc mc;
-
- mc.cmd = XEN_MC_msrinject;
- mc.interface_version = XEN_MCA_INTERFACE_VERSION;
- mc.u.mc_msrinject = msr_inj;
-
- return xc_mca_op(xc_handle, &mc);
-}
-
-static unsigned int mca_cpuinfo(xc_interface *xc_handle)
-{
- struct xen_mc mc;
-
- memset(&mc, 0, sizeof(struct xen_mc));
-
- mc.cmd = XEN_MC_physcpuinfo;
- mc.interface_version = XEN_MCA_INTERFACE_VERSION;
-
- if (!xc_mca_op(xc_handle, &mc))
- return mc.u.mc_physcpuinfo.ncpus;
- else
- return 0;
-}
-
-static int inject_cmci(xc_interface *xc_handle, unsigned int cpu_nr)
-{
- struct xen_mc mc;
- unsigned int nr_cpus;
-
- memset(&mc, 0, sizeof(struct xen_mc));
-
- nr_cpus = mca_cpuinfo(xc_handle);
- if (!nr_cpus)
- err(xc_handle, "Failed to get mca_cpuinfo");
- if (cpu_nr >= nr_cpus)
- err(xc_handle, "-c %u is larger than %u", cpu_nr, nr_cpus - 1);
-
- mc.cmd = XEN_MC_inject_v2;
- mc.interface_version = XEN_MCA_INTERFACE_VERSION;
-
- mc.u.mc_inject_v2.flags |= XEN_MC_INJECT_CPU_BROADCAST;
- mc.u.mc_inject_v2.flags |= XEN_MC_INJECT_TYPE_CMCI;
- mc.u.mc_inject_v2.cpumap.nr_bits = nr_cpus;
-
- return xc_mca_op(xc_handle, &mc);
-}
-
-static int inject_mce(xc_interface *xc_handle, int cpu_nr)
-{
- struct xen_mc mc;
-
- memset(&mc, 0, sizeof(struct xen_mc));
-
- mc.cmd = XEN_MC_mceinject;
- mc.interface_version = XEN_MCA_INTERFACE_VERSION;
- mc.u.mc_mceinject.mceinj_cpunr = cpu_nr;
-
- return xc_mca_op(xc_handle, &mc);
-}
-
-static int inject_lmce(xc_interface *xc_handle, unsigned int cpu)
-{
- uint8_t *cpumap = NULL;
- size_t cpumap_size, line, shift;
- unsigned int nr_cpus;
- int ret;
-
- nr_cpus = mca_cpuinfo(xc_handle);
- if ( !nr_cpus )
- err(xc_handle, "Failed to get mca_cpuinfo");
- if ( cpu >= nr_cpus )
- err(xc_handle, "-c %u is larger than %u", cpu, nr_cpus - 1);
-
- cpumap_size = (nr_cpus + 7) / 8;
- cpumap = malloc(cpumap_size);
- if ( !cpumap )
- err(xc_handle, "Failed to allocate cpumap\n");
- memset(cpumap, 0, cpumap_size);
- line = cpu / 8;
- shift = cpu % 8;
- memset(cpumap + line, 1 << shift, 1);
-
- ret = xc_mca_op_inject_v2(xc_handle, XEN_MC_INJECT_TYPE_LMCE,
- cpumap, cpumap_size * 8);
-
- free(cpumap);
- return ret;
-}
-
-static uint64_t bank_addr(int bank, int type)
-{
- uint64_t addr;
-
- switch ( type )
- {
- case MCi_type_CTL:
- case MCi_type_STATUS:
- case MCi_type_ADDR:
- case MCi_type_MISC:
- addr = MSR_IA32_MC0_CTL + (bank * 4) + type;
- break;
- case MCi_type_CTL2:
- addr = MSR_IA32_MC0_CTL2 + bank;
- break;
- default:
- addr = INVALID_MSR;
- break;
- }
-
- return addr;
-}
-
-static int add_msr_intpose(xc_interface *xc_handle,
- uint32_t cpu_nr,
- uint32_t flags,
- uint64_t msr,
- uint64_t val,
- domid_t domid)
-{
- uint32_t count;
-
- if ( (msr_inj.mcinj_count &&
- (cpu_nr != msr_inj.mcinj_cpunr || flags != msr_inj.mcinj_flags ||
- domid != msr_inj.mcinj_domid)) ||
- msr_inj.mcinj_count == MC_MSRINJ_MAXMSRS )
- {
- flush_msr_inj(xc_handle);
- init_msr_inj();
- }
- count= msr_inj.mcinj_count;
-
- if ( !count )
- {
- msr_inj.mcinj_cpunr = cpu_nr;
- msr_inj.mcinj_flags = flags;
- msr_inj.mcinj_domid = domid;
- }
- msr_inj.mcinj_msr[count].reg = msr;
- msr_inj.mcinj_msr[count].value = val;
- msr_inj.mcinj_count++;
-
- return 0;
-}
-
-static int add_msr_bank_intpose(xc_interface *xc_handle,
- uint32_t cpu_nr,
- uint32_t flags,
- uint32_t type,
- uint32_t bank,
- uint64_t val,
- domid_t domid)
-{
- uint64_t msr;
-
- msr = bank_addr(bank, type);
- if ( msr == INVALID_MSR )
- return -1;
- return add_msr_intpose(xc_handle, cpu_nr, flags, msr, val, domid);
-}
-
-static int inject_mcg_status(xc_interface *xc_handle,
- uint32_t cpu_nr,
- uint64_t val,
- domid_t domid)
-{
- return add_msr_intpose(xc_handle, cpu_nr, MC_MSRINJ_F_INTERPOSE,
- MSR_IA32_MCG_STATUS, val, domid);
-}
-
-static int inject_mci_status(xc_interface *xc_handle,
- uint32_t cpu_nr,
- uint64_t bank,
- uint64_t val,
- domid_t domid)
-{
- return add_msr_bank_intpose(xc_handle, cpu_nr, MC_MSRINJ_F_INTERPOSE,
- MCi_type_STATUS, bank, val, domid);
-}
-
-static int inject_mci_misc(xc_interface *xc_handle,
- uint32_t cpu_nr,
- uint64_t bank,
- uint64_t val,
- domid_t domid)
-{
- return add_msr_bank_intpose(xc_handle, cpu_nr, MC_MSRINJ_F_INTERPOSE,
- MCi_type_MISC, bank, val, domid);
-}
-
-static int inject_mci_addr(xc_interface *xc_handle,
- uint32_t cpu_nr,
- uint64_t bank,
- uint64_t val,
- domid_t domid)
-{
- return add_msr_bank_intpose(xc_handle, cpu_nr,
- MC_MSRINJ_F_INTERPOSE |
- ((domid >= DOMID_FIRST_RESERVED &&
- domid != DOMID_SELF) ?
- 0 : MC_MSRINJ_F_GPADDR),
- MCi_type_ADDR, bank, val, domid);
-}
-
-static int inject(xc_interface *xc_handle, struct mce_info *mce,
- uint32_t cpu_nr, uint32_t domain, uint64_t gaddr)
-{
- int ret = 0;
- uint8_t mcg_status = mce->mcg_stat;
-
- if ( lmce )
- {
- if ( mce->cmci )
- err(xc_handle, "No support to inject CMCI as LMCE");
- mcg_status |= MCG_STATUS_LMCE;
- }
- ret = inject_mcg_status(xc_handle, cpu_nr, mcg_status, domain);
- if ( ret )
- err(xc_handle, "Failed to inject MCG_STATUS MSR");
-
- ret = inject_mci_status(xc_handle, cpu_nr,
- mce->bank, mce->mci_stat, domain);
- if ( ret )
- err(xc_handle, "Failed to inject MCi_STATUS MSR");
-
- ret = inject_mci_misc(xc_handle, cpu_nr,
- mce->bank, mce->mci_misc, domain);
- if ( ret )
- err(xc_handle, "Failed to inject MCi_MISC MSR");
-
- ret = inject_mci_addr(xc_handle, cpu_nr, mce->bank, gaddr, domain);
- if ( ret )
- err(xc_handle, "Failed to inject MCi_ADDR MSR");
-
- ret = flush_msr_inj(xc_handle);
- if ( ret )
- err(xc_handle, "Failed to inject MSR");
- if ( mce->cmci )
- ret = inject_cmci(xc_handle, cpu_nr);
- else if ( lmce )
- ret = inject_lmce(xc_handle, cpu_nr);
- else
- ret = inject_mce(xc_handle, cpu_nr);
- if ( ret )
- err(xc_handle, "Failed to inject MCE error");
-
- return 0;
-}
-
-static long xs_get_dom_mem(int domid)
-{
- char path[128];
- char *memstr;
- uint64_t mem;
- unsigned int plen;
- struct xs_handle *xs;
-
- xs = xs_open(0);
- if (!xs)
- return -1;
-
- sprintf(path, "/local/domain/%d/memory/target", domid);
- memstr = xs_read(xs, XBT_NULL, path, &plen);
- xs_close(xs);
-
- if (!memstr || !plen)
- return -1;
-
- mem = atoll(memstr)*1024;
- free(memstr);
-
- return mem;
-}
-
-static struct option opts[] = {
- {"cpu", 0, 0, 'c'},
- {"domain", 0, 0, 'd'},
- {"dump", 0, 0, 'D'},
- {"help", 0, 0, 'h'},
- {"page", 0, 0, 'p'},
- {"lmce", 0, 0, 'l'},
- {"", 0, 0, '\0'}
-};
-
-static void help(void)
-{
- unsigned int i;
-
- printf("Usage: xen-mceinj [OPTION]...\n"
- "\n"
- "Mandatory arguments to long options are mandatory"
- "for short options too.\n"
- " -D, --dump dump addr info without error injection\n"
- " -c, --cpu=CPU target CPU\n"
- " -d, --domain=DOMID target domain, the default is Xen itself\n"
- " -h, --help print this page\n"
- " -p, --page=ADDR physical address to report\n"
- " -l, --lmce inject as LMCE (Intel only)\n"
- " -t, --type=ERROR error type\n");
-
- for ( i = 0; i < MCE_TABLE_SIZE; i++ )
- printf(" %2d : %s\n",
- i, mce_table[i].description);
-}
-
-int main(int argc, char *argv[])
-{
- int type = 0;
- int c, opt_index;
- uint32_t domid;
- xc_interface *xc_handle;
- unsigned int cpu_nr;
- uint64_t gaddr, max_gpa;
-
- /* Default Value */
- domid = DOMID_XEN;
- gaddr = 0x180020;
- cpu_nr = 0;
-
- init_msr_inj();
- xc_handle = xc_interface_open(0, 0, 0);
- if ( !xc_handle ) {
- Lprintf("Failed to get xc interface");
- exit(EXIT_FAILURE);
- }
-
- while ( 1 ) {
- c = getopt_long(argc, argv, "c:Dd:t:hp:l", opts, &opt_index);
- if ( c == -1 )
- break;
- switch ( c ) {
- case 'D':
- dump=1;
- break;
- case 'c':
- cpu_nr = strtoul(optarg, &optarg, 10);
- if ( strlen(optarg) != 0 )
- err(xc_handle, "Please input a digit parameter for CPU");
- break;
- case 'd':
- domid = strtol(optarg, &optarg, 10);
- if ( strlen(optarg) != 0 )
- err(xc_handle, "Please input a digit parameter for domain");
- break;
- case 'p':
- gaddr = strtol(optarg, &optarg, 0);
- if ( strlen(optarg) != 0 )
- err(xc_handle, "Please input correct page address");
- break;
- case 't':
- type = strtol(optarg, NULL, 0);
- break;
- case 'l':
- lmce = 1;
- break;
- case 'h':
- default:
- help();
- return 0;
- }
- }
-
- if ( domid != DOMID_XEN ) {
- max_gpa = xs_get_dom_mem(domid);
- Lprintf("get domain %d max gpa is: 0x%lx", domid, max_gpa);
- if ( gaddr >= max_gpa )
- err(xc_handle, "Fail: gaddr exceeds max_gpa 0x%lx", max_gpa);
- }
- Lprintf("get gaddr of error inject is: 0x%lx", gaddr);
-
- if ( dump ) {
- if ( domid == DOMID_XEN )
- Lprintf("Xen: gaddr=0x%lx", gaddr);
- else
- Lprintf("Dom%d: gaddr=0x%lx", domid, gaddr);
- goto out;
- }
-
- if ( type < 0 || type >= MCE_TABLE_SIZE ) {
- err(xc_handle, "Unsupported error type");
- goto out;
- }
-
- inject(xc_handle, &mce_table[type], cpu_nr, domid, gaddr);
-
- out:
- xc_interface_close(xc_handle);
- return 0;
-}