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@xxxxxxx> --- x86/amd_sev.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) 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(); -- 2.34.1