diff mbox series

[v2] nSVM: Add a test for the P (present) bit in NPT entry

Message ID 20200903012851.22299-2-krish.sadhukhan@oracle.com (mailing list archive)
State New, archived
Headers show
Series [v2] nSVM: Add a test for the P (present) bit in NPT entry | expand

Commit Message

Krish Sadhukhan Sept. 3, 2020, 1:28 a.m. UTC
If the P (present) bit in an NPT entry is cleared, page translation will
fail at the level where the final guest physical address is translated to
the host physical address and the guest will VMEXIT to the host with an
exit code of 0x400 (#NPF). Additionally, the EXITINFO1 field will have
the following bit pattern set on VMEXIT:

	Bit# 0: Cleared due to the nested page not being preset (P bit cleared)
	Bit# 1: Cleared due to the access to the NPT being a read-access
	Bit# 2: Set due to the access to the NPT by MMU is a user-level access
	Bit# 3: Cleared due to no reserved bits being set in the NPT entry
	Bit# 4: Cleared due to the NPT walk being a code-read-access
	Bit# 32: Set due to the NPF occurring at the level where the final
		 guest physical address gets translated to host physical address

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
---
 x86/svm_tests.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
diff mbox series

Patch

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 1908c7c..f47d21d 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -720,6 +720,32 @@  static bool npt_nx_check(struct svm_test *test)
            && (vmcb->control.exit_info_1 == 0x100000015ULL);
 }
 
+static void npt_np_prepare(struct svm_test *test)
+{
+	u64 *pte;
+
+	scratch_page = alloc_page();
+	vmcb_ident(vmcb);
+	pte = npt_get_pte((u64)scratch_page);
+
+	*pte &= ~1ULL;
+}
+
+static void npt_np_test(struct svm_test *test)
+{
+	(void) *(volatile u64 *)scratch_page;
+}
+
+static bool npt_np_check(struct svm_test *test)
+{
+	u64 *pte = npt_get_pte((u64)scratch_page);
+
+	*pte |= 1ULL;
+
+	return (vmcb->control.exit_code == SVM_EXIT_NPF)
+	    && (vmcb->control.exit_info_1 == 0x100000004ULL);
+}
+
 static void npt_us_prepare(struct svm_test *test)
 {
     u64 *pte;
@@ -2119,6 +2145,9 @@  struct svm_test svm_tests[] = {
     { "npt_nx", npt_supported, npt_nx_prepare,
       default_prepare_gif_clear, null_test,
       default_finished, npt_nx_check },
+    { "npt_np", npt_supported, npt_np_prepare,
+      default_prepare_gif_clear, npt_np_test,
+      default_finished, npt_np_check },
     { "npt_us", npt_supported, npt_us_prepare,
       default_prepare_gif_clear, npt_us_test,
       default_finished, npt_us_check },