diff mbox series

[kvm-unit-tests,RFC,13/13] x86 AMD SEV-SNP: Test-2: Perform Intermix to 2M private to 2M shared PSCs

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

Commit Message

Paluri, PavanKumar April 19, 2024, 12:57 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 a write operation on these un-encrypted pages.
3. Performs partial page state changes (shared->private) on first 256
   sub-pages and conducts a re-validation ('pvalidate') check on one of
   these entries to ensure its state has been changed to private.
4. Performs write test on the other set of sub-pages whose state is shared.
5. Performs PSC from 2M intermixed state to private, backed up with a
   re-validation check on the 2M range to ensure successfull conversion.
6. Performs PSC from 2M private to 2M shared followed by a write
   operation to ensure the 2M page is successfully changed to shared.

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

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

Patch

diff --git a/x86/amd_sev.c b/x86/amd_sev.c
index 7b53ef9c44d0..94944fb80a70 100644
--- a/x86/amd_sev.c
+++ b/x86/amd_sev.c
@@ -657,6 +657,32 @@  static void __test_sev_psc_private(unsigned long vaddr, struct ghcb *ghcb,
 	       "Expected 2M page state: Private");
 }
 
+static void __test_sev_psc_shared(unsigned long vaddr, struct ghcb *ghcb,
+				  bool large_page, pteval_t *pte)
+{
+	allow_noupdate = true;
+
+	set_pte_encrypted((unsigned long)vaddr, 1 << INTERMIX_PSC_ORDER);
+
+	/* Convert the intermixed 2M range to 2M private */
+	sev_set_pages_state(vaddr, 512, SNP_PAGE_STATE_PRIVATE, ghcb,
+			    large_page);
+
+	allow_noupdate = false;
+
+	report(is_validated_private_page(vaddr, large_page, 1),
+	       "Expected 2M page state: Private");
+
+	/* 2M private->shared conversion */
+	sev_set_pages_state(vaddr, 512, SNP_PAGE_STATE_SHARED, ghcb,
+			    large_page);
+
+	set_pte_decrypted((unsigned long)vaddr, 1 << INTERMIX_PSC_ORDER);
+
+	report(!test_write((unsigned long)vaddr, 512),
+	       "Write to a 2M un-encrypted range");
+}
+
 static void test_sev_psc_intermix(bool is_private)
 {
 	unsigned long *vm_page;
@@ -714,6 +740,9 @@  static void test_sev_psc_intermix(bool is_private)
 	if (is_private)
 		__test_sev_psc_private((unsigned long)vm_page, ghcb,
 				       large_page, pte);
+	else
+		__test_sev_psc_shared((unsigned long)vm_page, ghcb,
+				      large_page, pte);
 
 	/* Cleanup */
 	free_pages_by_order(vm_page, INTERMIX_PSC_ORDER);
@@ -724,6 +753,11 @@  static void test_sev_psc_intermix_to_private(void)
 	test_sev_psc_intermix(true);
 }
 
+static void test_sev_psc_intermix_to_shared(void)
+{
+	test_sev_psc_intermix(false);
+}
+
 int main(void)
 {
 	int rtn;
@@ -738,6 +772,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();