diff mbox series

[kvm-unit-tests,v2,14/16] x86 AMD SEV-SNP: Change guest pages from Intermix->Shared using GHCB NAE

Message ID 20240718124932.114121-15-papaluri@amd.com (mailing list archive)
State New, archived
Headers show
Series Introduce SEV-SNP support | expand

Commit Message

Paluri, PavanKumar July 18, 2024, 12:49 p.m. UTC
The test performs the following actions:
1. Allocates a 2M private page (512 4K entries) and performs 2M private
to shared conversion.
2. Performs partial page state changes (shared->private) on first 256 4K
entries and conducts a re-validation ('pvalidate') check on one of these
entries to ensure its state has been changed to private.
3. Performs PSC from intermixed state to shared state on the 2M large
page.
4. Conducts a write test on the shared pages to ensure page state change
has been successful.

The main goal of this test is to ensure 2M page state changes are
handled properly even if 2M range contains a mix of private/shared
pages.

Signed-off-by: Pavan Kumar Paluri <papaluri@amd.com>
---
 x86/amd_sev.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
diff mbox series

Patch

diff --git a/x86/amd_sev.c b/x86/amd_sev.c
index fc385613b993..ae19f8ad6cc8 100644
--- a/x86/amd_sev.c
+++ b/x86/amd_sev.c
@@ -303,6 +303,21 @@  static void __test_sev_psc_private(unsigned long vaddr, struct ghcb *ghcb,
 	       "Expected page state: Private");
 }
 
+static void __test_sev_psc_shared(unsigned long vaddr, struct ghcb *ghcb,
+				  int npages, bool allow_noupdate)
+{
+	/* Convert the whole 2M range to shared */
+	sev_set_pages_state(vaddr, npages, SNP_PAGE_STATE_SHARED, ghcb,
+			    allow_noupdate);
+
+	set_pte_decrypted(vaddr, npages);
+
+	/* Conduct a write test to ensure pages are in expected state */
+	report(!test_write(vaddr, npages),
+	       "Write to %d unencrypted 2M pages after private->shared conversion",
+	       npages / (1 << ORDER_2M));
+}
+
 static void test_sev_psc_intermix(bool to_private)
 {
 	unsigned long vaddr;
@@ -331,6 +346,8 @@  static void test_sev_psc_intermix(bool to_private)
 	/* Now convert all the pages back to private */
 	if (to_private)
 		__test_sev_psc_private(vaddr, ghcb, (SEV_ALLOC_PAGE_COUNT) / 2, true);
+	else
+		__test_sev_psc_shared(vaddr, ghcb, (SEV_ALLOC_PAGE_COUNT) / 2, true);
 
 	/* Free up all the used pages */
 	snp_free_pages(SEV_ALLOC_ORDER - 1, (SEV_ALLOC_PAGE_COUNT) / 2,
@@ -343,6 +360,12 @@  static void test_sev_psc_intermix_to_private(void)
 	test_sev_psc_intermix(true);
 }
 
+static void test_sev_psc_intermix_to_shared(void)
+{
+	report_info("TEST: 2M Intermixed to Shared PSC test");
+	test_sev_psc_intermix(false);
+}
+
 int main(void)
 {
 	int rtn;
@@ -363,6 +386,7 @@  int main(void)
 		test_sev_psc_ghcb_msr();
 		test_sev_psc_ghcb_nae();
 		test_sev_psc_intermix_to_private();
+		test_sev_psc_intermix_to_shared();
 	}
 
 	return report_summary();