update the KVM-SRAO test README file and related files

Add more content into it to make it more readable and
operable. Besides the update for README file. Some related
patches are added into mce-test suite, too.

Signed-off-by: Chen Gong <gong.chen@linux.intel.com>
diff --git a/kvm/README b/kvm/README
index c625b2d..97fd9bf 100644
--- a/kvm/README
+++ b/kvm/README
@@ -26,6 +26,9 @@
 * Linux Kernel:
   Version 2.6.32 or newer, with MCA high level handlers enabled.
 
+* mce-inject
+  A tool to inject mce error into kernel
+
 * 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).
@@ -33,25 +36,77 @@
 * simple_process:
   A process constantly access the allocated memeory. (../tools/simple_process)
 
+* kpartx:
+  A tool to list partition mappings from partition tables
+
+* (optionally) losetup
+  A tool to set up and control loop devices
+
+* (optionally) pvdisplay/vgchange:
+  A tool to display/change physical volume attribute
+
+* (optionally) ssh-keygen
+  A tool to provide the authentication key generation, management and conversion
+
+Test method
+---------------
+- Start a process in the guest OS, get a virtual address from guest OS
+
+- 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
+
+- (optionally) Write to the address from the guest, i.e attempt to
+  write to the poisoned page from the guest.
+
+the expected result:
+
+HOST system dmesg:
+
+...
+Machine check injector initialized
+Triggering MCE exception on CPU 0
+Disabling lock debugging due to kernel taint
+[Hardware Error]: Machine check events logged
+MCE exception done on CPU 0
+MCE 0x806324: Killing qemu-system-x86:8829 early due to hardware memory corruption
+MCE 0x806324: dirty LRU page recovery: Recovered
+...
+
+
+GUEST system dmesg:
+...
+[Hardware Error]: Machine check events logged
+MCE 0x75925: Killing simple_process:2273 early due to hardware memory corruption
+MCE 0x75925: dirty LRU page recovery : Recovered
+...
+
+
 Installation
 ---------------
-1. Build host kernel with
+1. Build *host* kernel with
 	CONFIG_KVM=y
 	CONFIG_KVM_INTEL=y
-2. Create a testing dirctory on host system and put the host test scripts
-   and test tool (page-types) into it.
-   By default, the testing directory is /test.
-3. Use ssh-keygen to generate public and privite keys, and copy them into the
-   testing directory on host system.
-4. Mount guest image
-5. Create a testing dirctory on guest system and copy guest test script and
-   tools (page-types, simple_process) into it.
-   By default, the testing directory is /test.
-6. Use qemu to start guest system, install page-types and simple_process on
-   guest system.
-     gcc -o page-types page-types.c
-     cd simple_process
-     make
+	CONFIG_X86_MCE=y
+	CONFIG_X86_MCE_INTEL=y
+	CONFIG_X86_MCE_INJECT=y or CONFIG_X86_MCE_INJECT=m
+
+   and following config both on *host* and *guest*
+	CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
+	CONFIG_MEMORY_FAILURE=y
+
+   NOTE: if the 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/
+   Please ensure *SDL-devel* library is installed on the host machine, otherwise
+   only VNC can be used substituing local graphic output.
 
 Start Testing
 ---------------
diff --git a/kvm/patches/fake_ser_p.patch b/kvm/patches/fake_ser_p.patch
new file mode 100644
index 0000000..4b22544
--- /dev/null
+++ b/kvm/patches/fake_ser_p.patch
@@ -0,0 +1,47 @@
+From ae0d704daf02ef943bf9e12413ad489358879508 Mon Sep 17 00:00:00 2001
+From: Chen Gong <gong.chen@linux.intel.com>
+Date: Tue, 15 Mar 2011 10:23:56 +0800
+Subject: [PATCH] fake_ser_p
+
+this patch is only needed on the machines not supporting SRAO
+
+Signed-off-by: Chen Gong <gong.chen@linux.intel.com>
+---
+ arch/x86/kernel/cpu/mcheck/mce.c |   12 +++++++++++-
+ 1 files changed, 11 insertions(+), 1 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
+index d916183..d23ea36 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -2195,7 +2195,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fake_panic_fops, fake_panic_get,
+ 
+ static int __init mcheck_debugfs_init(void)
+ {
+-	struct dentry *dmce, *ffake_panic;
++	struct dentry *dmce, *ffake_panic, *ffake_ser_p;
+ 
+ 	dmce = mce_get_debugfs_dir();
+ 	if (!dmce)
+@@ -2204,8 +2204,18 @@ static int __init mcheck_debugfs_init(void)
+ 					  &fake_panic_fops);
+ 	if (!ffake_panic)
+ 		return -ENOMEM;
++	ffake_ser_p = debugfs_create_u32("fake_ser_p", 0644, dmce,
++					 (u32 *)&mce_ser);
++	if (!ffake_ser_p)
++		goto err_clean;
+ 
+ 	return 0;
++err_clean:
++	if (ffake_ser_p)
++		debugfs_remove(ffake_ser_p);
++	if (ffake_panic)
++		debugfs_remove(ffake_panic);
++	return -ENOMEM;
+ }
+ late_initcall(mcheck_debugfs_init);
+ #endif
+-- 
+1.7.3.1.120.g38a18
+
diff --git a/kvm/patches/p2v.patch b/kvm/patches/p2v.patch
new file mode 100644
index 0000000..328212b
--- /dev/null
+++ b/kvm/patches/p2v.patch
@@ -0,0 +1,94 @@
+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
+