@@ -1421,3 +1421,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
14211421
14221422 return ret ;
14231423}
1424+
1425+ static int __check_host_shared_guest (struct pkvm_hyp_vm * vm , u64 * __phys , u64 ipa )
1426+ {
1427+ enum pkvm_page_state state ;
1428+ struct hyp_page * page ;
1429+ kvm_pte_t pte ;
1430+ u64 phys ;
1431+ s8 level ;
1432+ int ret ;
1433+
1434+ ret = kvm_pgtable_get_leaf (& vm -> pgt , ipa , & pte , & level );
1435+ if (ret )
1436+ return ret ;
1437+ if (level != KVM_PGTABLE_LAST_LEVEL )
1438+ return - E2BIG ;
1439+ if (!kvm_pte_valid (pte ))
1440+ return - ENOENT ;
1441+
1442+ state = guest_get_page_state (pte , ipa );
1443+ if (state != PKVM_PAGE_SHARED_BORROWED )
1444+ return - EPERM ;
1445+
1446+ phys = kvm_pte_to_phys (pte );
1447+ ret = check_range_allowed_memory (phys , phys + PAGE_SIZE );
1448+ if (WARN_ON (ret ))
1449+ return ret ;
1450+
1451+ page = hyp_phys_to_page (phys );
1452+ if (page -> host_state != PKVM_PAGE_SHARED_OWNED )
1453+ return - EPERM ;
1454+ if (WARN_ON (!page -> host_share_guest_count ))
1455+ return - EINVAL ;
1456+
1457+ * __phys = phys ;
1458+
1459+ return 0 ;
1460+ }
1461+
1462+ int __pkvm_host_unshare_guest (u64 gfn , struct pkvm_hyp_vm * vm )
1463+ {
1464+ u64 ipa = hyp_pfn_to_phys (gfn );
1465+ struct hyp_page * page ;
1466+ u64 phys ;
1467+ int ret ;
1468+
1469+ host_lock_component ();
1470+ guest_lock_component (vm );
1471+
1472+ ret = __check_host_shared_guest (vm , & phys , ipa );
1473+ if (ret )
1474+ goto unlock ;
1475+
1476+ ret = kvm_pgtable_stage2_unmap (& vm -> pgt , ipa , PAGE_SIZE );
1477+ if (ret )
1478+ goto unlock ;
1479+
1480+ page = hyp_phys_to_page (phys );
1481+ page -> host_share_guest_count -- ;
1482+ if (!page -> host_share_guest_count )
1483+ WARN_ON (__host_set_page_state_range (phys , PAGE_SIZE , PKVM_PAGE_OWNED ));
1484+
1485+ unlock :
1486+ guest_unlock_component (vm );
1487+ host_unlock_component ();
1488+
1489+ return ret ;
1490+ }
0 commit comments