From: Prasad Joshi <[email protected]>

Signed-off-by: Prasad Joshi <[email protected]>
---
 lib/x86/msr.h |   10 ++++++++++
 x86/svm.c     |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index 509a421..0e602d0 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -402,5 +402,15 @@
 #define MSR_VM_CR                       0xc0010114
 #define MSR_VM_IGNNE                    0xc0010115
 #define MSR_VM_HSAVE_PA                 0xc0010117
+#define MSR_SVM_KEY                    0xc0010118
+
+/* VM CR bits: */
+#define _VM_CR_DPD             0 /* disable internal debugging */
+#define _VM_CR_R_INIT          1 /* non-interrupted INIT causes #SX exception 
*/
+#define _VM_CR_DIS_A20M                2 /* disable A20 masking */
+#define _VM_CR_LOCK            3 /* svm lock */
+#define _VM_CR_SVMDIS          4 /* disable svm */
+
+#define VM_CR_LOCK             (1 << _VM_CR_LOCK)
 
 #endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/x86/svm.c b/x86/svm.c
index d51e7ec..6d39ff1 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -241,6 +241,63 @@ static bool null_check(struct test *test)
     return test->vmcb->control.exit_code == SVM_EXIT_VMMCALL;
 }
 
+static bool svm_lock_supported(void)
+{
+       /*
+        * Support for SVM-Lock is indicated by EDX bit 2 as returned by CPUID
+        * function 8000_000Ah.
+        */
+       return (cpuid(0x8000000A).d & 4);
+}
+
+static void svm_lock_test(struct test *test)
+{
+       const int no_tests = 6;
+       const u64 svm_key  = 0x1234567890;
+
+       test->scratch = no_tests;
+
+       /* reading SVM_KEY must always return 0 */
+       if (!rdmsr(MSR_SVM_KEY))
+               test->scratch--;
+
+       /* set the key */
+       wrmsr(MSR_SVM_KEY, svm_key);
+
+       /* reading SVM_KEY must always return 0 */
+       if (!rdmsr(MSR_SVM_KEY))
+               test->scratch--;
+
+       /* set SVM lock */
+       wrmsr(MSR_VM_CR, rdmsr(MSR_VM_CR) | VM_CR_LOCK);
+       if (rdmsr(MSR_VM_CR) & VM_CR_LOCK) {
+               /* lock is set */
+               test->scratch--;
+       }
+
+       /* compare with 0 key */
+       wrmsr(MSR_SVM_KEY, 0);
+       if (rdmsr(MSR_VM_CR) & VM_CR_LOCK)
+               test->scratch--;
+
+       /* compare with incorrect key */
+       wrmsr(MSR_SVM_KEY, 0x12);
+       if (rdmsr(MSR_VM_CR) & VM_CR_LOCK)
+               test->scratch--;
+
+       /* compare with correct key */
+       wrmsr(MSR_SVM_KEY, svm_key);
+       if (!(rdmsr(MSR_VM_CR) & VM_CR_LOCK)) {
+               /* lock no longer set */
+               test->scratch--;
+       }
+}
+
+static bool svm_lock_check(struct test *test)
+{
+       return !test->scratch;
+}
+
 static void prepare_no_vmrun_int(struct test *test)
 {
     test->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMRUN);
@@ -746,6 +803,8 @@ static bool lat_svm_insn_check(struct test *test)
 static struct test tests[] = {
     { "null", default_supported, default_prepare, null_test,
       default_finished, null_check },
+    { "SVM Lock", svm_lock_supported, default_prepare, svm_lock_test,
+      default_finished, svm_lock_check },
     { "vmrun", default_supported, default_prepare, test_vmrun,
        default_finished, check_vmrun },
     { "vmrun intercept check", default_supported, prepare_no_vmrun_int,
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to