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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxx>
Signed-off-by: Pavan Kumar Paluri <papaluri@xxxxxxx>
---
 x86/amd_sev.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

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();
-- 
2.34.1





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux