All of lore.kernel.org
 help / color / mirror / Atom feed
From: Krish Sadhukhan <krish.sadhukhan@oracle.com>
To: kvm@vger.kernel.org
Cc: pbonzini@redhat.com, jmattson@google.com, mlevitsk@redhat.com
Subject: [PATCH kvm-unit-tests 3/3] nSVM: Test G_PAT fields
Date: Tue, 18 Jan 2022 14:14:49 -0500	[thread overview]
Message-ID: <20220118191449.38852-4-krish.sadhukhan@oracle.com> (raw)
In-Reply-To: <20220118191449.38852-1-krish.sadhukhan@oracle.com>

According to section "Nested Paging and VMRUN/#VMEXIT" in APM vol 2, the
following guest state is illegal:

    "Any G_PAT.PA field has an unsupported type encoding or any
     reserved field in G_PAT has a nonzero value."

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
---
 lib/x86/asm/page.h | 11 ++++++++
 x86/svm.c          |  8 ++++++
 x86/svm.h          |  1 +
 x86/svm_tests.c    | 66 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+)

diff --git a/lib/x86/asm/page.h b/lib/x86/asm/page.h
index fc14160..9ff9329 100644
--- a/lib/x86/asm/page.h
+++ b/lib/x86/asm/page.h
@@ -57,5 +57,16 @@ typedef unsigned long pgd_t;
 #define PGDIR_BITS(lvl)        (((lvl) - 1) * PGDIR_WIDTH + PAGE_SHIFT)
 #define PGDIR_OFFSET(va, lvl)  (((va) >> PGDIR_BITS(lvl)) & PGDIR_MASK)
 
+#ifdef __x86_64__
+enum {
+	PAT_UC = 0,             /* uncached */
+	PAT_WC = 1,             /* Write combining */
+	PAT_WT = 4,             /* Write Through */
+	PAT_WP = 5,             /* Write Protected */
+	PAT_WB = 6,             /* Write Back (default) */
+	PAT_UC_MINUS = 7,       /* UC, but can be overridden by MTRR */
+};
+#endif
+
 #endif /* !__ASSEMBLY__ */
 #endif
diff --git a/x86/svm.c b/x86/svm.c
index d03f011..c949003 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -94,6 +94,14 @@ bool pat_supported(void)
 	return this_cpu_has(X86_FEATURE_PAT);
 }
 
+bool pat_valid(u64 data)
+{
+	if (data & 0xF8F8F8F8F8F8F8F8ull)
+		return false;
+	/* 0, 1, 4, 5, 6, 7 are valid values.  */
+	return (data | ((data & 0x0202020202020202ull) << 1)) == data;
+}
+
 int get_test_stage(struct svm_test *test)
 {
 	barrier();
diff --git a/x86/svm.h b/x86/svm.h
index d4db4c1..d4c6e1c 100644
--- a/x86/svm.h
+++ b/x86/svm.h
@@ -410,6 +410,7 @@ void default_prepare_gif_clear(struct svm_test *test);
 bool default_finished(struct svm_test *test);
 bool npt_supported(void);
 bool pat_supported(void);
+bool pat_valid(u64 data);
 int get_test_stage(struct svm_test *test);
 void set_test_stage(struct svm_test *test, int s);
 void inc_test_stage(struct svm_test *test);
diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 8ad6122..4536362 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -2547,6 +2547,71 @@ static void guest_rflags_test_db_handler(struct ex_regs *r)
 	r->rflags &= ~X86_EFLAGS_TF;
 }
 
+#define G_PAT_VMRUN(nested_ctl, val, i, field_val)		\
+{								\
+	u32 ret, xret;						\
+								\
+	if (nested_ctl) {					\
+		if (pat_valid(val))				\
+			xret = SVM_EXIT_VMMCALL;		\
+		else						\
+			xret = SVM_EXIT_ERR;			\
+	} else {						\
+		xret = SVM_EXIT_VMMCALL;			\
+	}							\
+	vmcb->save.g_pat = val;					\
+	ret = svm_vmrun();					\
+	report (ret == xret, "Test G_PAT[%d]: %lx, wanted "	\
+           "exit 0x%x, got 0x%x", i, field_val, xret, ret);	\
+}
+
+#define TEST_G_PAT(g_pat_saved, nested_ctl)			\
+{								\
+	int i, field_shift;					\
+	u64 g_pat_mask, field_val, val, j;			\
+								\
+	for (i = 0; i < 8; i++) {				\
+		/*						\
+		 * Test each PAT field's encodings and		\
+		 * reserved values				\
+		 */						\
+		field_shift = i * 8;				\
+		g_pat_mask = ~(0x7ul << field_shift) &		\
+				g_pat_saved;			\
+		for (j = PAT_UC; j <= PAT_UC_MINUS; j++) {	\
+			val = g_pat_mask | j << field_shift;	\
+			G_PAT_VMRUN(nested_ctl, val, i, j);	\
+		}						\
+		field_shift = i * 8 + 3;			\
+		g_pat_mask = ~(0x1ful << field_shift) &		\
+				g_pat_saved;			\
+		for (j = 0; j < 5; j++) {			\
+			field_val = 1ul << j;			\
+			val = g_pat_mask |			\
+			      field_val << field_shift;		\
+			G_PAT_VMRUN(nested_ctl, val, i,		\
+				    field_val);			\
+		}						\
+	}							\
+}
+
+static void test_g_pat(void)
+{
+	u64 g_pat_saved = vmcb->save.g_pat;
+	u64 nested_ctl_saved = vmcb->control.nested_ctl;
+
+	if (!npt_supported() || !pat_supported()) {
+		report_skip("NPT or PAT or both not supported");
+		return;
+	}
+
+	TEST_G_PAT(g_pat_saved, (vmcb->control.nested_ctl = 0));
+	TEST_G_PAT(g_pat_saved, (vmcb->control.nested_ctl = 1));
+
+	vmcb->control.nested_ctl = nested_ctl_saved;
+	vmcb->save.g_pat = g_pat_saved;
+}
+
 static void svm_guest_state_test(void)
 {
 	test_set_guest(basic_guest_main);
@@ -2557,6 +2622,7 @@ static void svm_guest_state_test(void)
 	test_dr();
 	test_msrpm_iopm_bitmap_addrs();
 	test_canonicalization();
+	test_g_pat();
 }
 
 extern void guest_rflags_test_guest(struct svm_test *test);
-- 
2.27.0


      parent reply	other threads:[~2022-01-18 20:10 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-18 19:14 [PATCH KVM 0/3] nSVM: Fix PAT in VMCB02 and check PAT in VMCB12 Krish Sadhukhan
2022-01-18 19:14 ` [PATCH KVM 1/3] " Krish Sadhukhan
2022-01-18 19:14 ` [PATCH kvm-unit-tests 2/3] SVM: Add a helpter function for checking if PAT is supported by the VCPU Krish Sadhukhan
2022-01-18 19:14 ` Krish Sadhukhan [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220118191449.38852-4-krish.sadhukhan@oracle.com \
    --to=krish.sadhukhan@oracle.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=mlevitsk@redhat.com \
    --cc=pbonzini@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.