@@ -685,36 +685,6 @@ static int host_request_owned_transition(u64 *completer_addr,
685685 return __host_check_page_state_range (addr , size , PKVM_PAGE_OWNED );
686686}
687687
688- static int host_request_unshare (u64 * completer_addr ,
689- const struct pkvm_mem_transition * tx )
690- {
691- u64 size = tx -> nr_pages * PAGE_SIZE ;
692- u64 addr = tx -> initiator .addr ;
693-
694- * completer_addr = tx -> initiator .host .completer_addr ;
695- return __host_check_page_state_range (addr , size , PKVM_PAGE_SHARED_OWNED );
696- }
697-
698- static int host_initiate_share (u64 * completer_addr ,
699- const struct pkvm_mem_transition * tx )
700- {
701- u64 size = tx -> nr_pages * PAGE_SIZE ;
702- u64 addr = tx -> initiator .addr ;
703-
704- * completer_addr = tx -> initiator .host .completer_addr ;
705- return __host_set_page_state_range (addr , size , PKVM_PAGE_SHARED_OWNED );
706- }
707-
708- static int host_initiate_unshare (u64 * completer_addr ,
709- const struct pkvm_mem_transition * tx )
710- {
711- u64 size = tx -> nr_pages * PAGE_SIZE ;
712- u64 addr = tx -> initiator .addr ;
713-
714- * completer_addr = tx -> initiator .host .completer_addr ;
715- return __host_set_page_state_range (addr , size , PKVM_PAGE_OWNED );
716- }
717-
718688static int host_initiate_donation (u64 * completer_addr ,
719689 const struct pkvm_mem_transition * tx )
720690{
@@ -802,31 +772,6 @@ static bool __hyp_ack_skip_pgtable_check(const struct pkvm_mem_transition *tx)
802772 tx -> initiator .id != PKVM_ID_HOST );
803773}
804774
805- static int hyp_ack_share (u64 addr , const struct pkvm_mem_transition * tx ,
806- enum kvm_pgtable_prot perms )
807- {
808- u64 size = tx -> nr_pages * PAGE_SIZE ;
809-
810- if (perms != PAGE_HYP )
811- return - EPERM ;
812-
813- if (__hyp_ack_skip_pgtable_check (tx ))
814- return 0 ;
815-
816- return __hyp_check_page_state_range (addr , size , PKVM_NOPAGE );
817- }
818-
819- static int hyp_ack_unshare (u64 addr , const struct pkvm_mem_transition * tx )
820- {
821- u64 size = tx -> nr_pages * PAGE_SIZE ;
822-
823- if (tx -> initiator .id == PKVM_ID_HOST && hyp_page_count ((void * )addr ))
824- return - EBUSY ;
825-
826- return __hyp_check_page_state_range (addr , size ,
827- PKVM_PAGE_SHARED_BORROWED );
828- }
829-
830775static int hyp_ack_donation (u64 addr , const struct pkvm_mem_transition * tx )
831776{
832777 u64 size = tx -> nr_pages * PAGE_SIZE ;
@@ -837,24 +782,6 @@ static int hyp_ack_donation(u64 addr, const struct pkvm_mem_transition *tx)
837782 return __hyp_check_page_state_range (addr , size , PKVM_NOPAGE );
838783}
839784
840- static int hyp_complete_share (u64 addr , const struct pkvm_mem_transition * tx ,
841- enum kvm_pgtable_prot perms )
842- {
843- void * start = (void * )addr , * end = start + (tx -> nr_pages * PAGE_SIZE );
844- enum kvm_pgtable_prot prot ;
845-
846- prot = pkvm_mkstate (perms , PKVM_PAGE_SHARED_BORROWED );
847- return pkvm_create_mappings_locked (start , end , prot );
848- }
849-
850- static int hyp_complete_unshare (u64 addr , const struct pkvm_mem_transition * tx )
851- {
852- u64 size = tx -> nr_pages * PAGE_SIZE ;
853- int ret = kvm_pgtable_hyp_unmap (& pkvm_pgtable , addr , size );
854-
855- return (ret != size ) ? - EFAULT : 0 ;
856- }
857-
858785static int hyp_complete_donation (u64 addr ,
859786 const struct pkvm_mem_transition * tx )
860787{
@@ -885,180 +812,6 @@ static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
885812 return check_page_state_range (& vm -> pgt , addr , size , & d );
886813}
887814
888- static int check_share (struct pkvm_mem_share * share )
889- {
890- const struct pkvm_mem_transition * tx = & share -> tx ;
891- u64 completer_addr ;
892- int ret ;
893-
894- switch (tx -> initiator .id ) {
895- case PKVM_ID_HOST :
896- ret = host_request_owned_transition (& completer_addr , tx );
897- break ;
898- default :
899- ret = - EINVAL ;
900- }
901-
902- if (ret )
903- return ret ;
904-
905- switch (tx -> completer .id ) {
906- case PKVM_ID_HYP :
907- ret = hyp_ack_share (completer_addr , tx , share -> completer_prot );
908- break ;
909- case PKVM_ID_FFA :
910- /*
911- * We only check the host; the secure side will check the other
912- * end when we forward the FFA call.
913- */
914- ret = 0 ;
915- break ;
916- default :
917- ret = - EINVAL ;
918- }
919-
920- return ret ;
921- }
922-
923- static int __do_share (struct pkvm_mem_share * share )
924- {
925- const struct pkvm_mem_transition * tx = & share -> tx ;
926- u64 completer_addr ;
927- int ret ;
928-
929- switch (tx -> initiator .id ) {
930- case PKVM_ID_HOST :
931- ret = host_initiate_share (& completer_addr , tx );
932- break ;
933- default :
934- ret = - EINVAL ;
935- }
936-
937- if (ret )
938- return ret ;
939-
940- switch (tx -> completer .id ) {
941- case PKVM_ID_HYP :
942- ret = hyp_complete_share (completer_addr , tx , share -> completer_prot );
943- break ;
944- case PKVM_ID_FFA :
945- /*
946- * We're not responsible for any secure page-tables, so there's
947- * nothing to do here.
948- */
949- ret = 0 ;
950- break ;
951- default :
952- ret = - EINVAL ;
953- }
954-
955- return ret ;
956- }
957-
958- /*
959- * do_share():
960- *
961- * The page owner grants access to another component with a given set
962- * of permissions.
963- *
964- * Initiator: OWNED => SHARED_OWNED
965- * Completer: NOPAGE => SHARED_BORROWED
966- */
967- static int do_share (struct pkvm_mem_share * share )
968- {
969- int ret ;
970-
971- ret = check_share (share );
972- if (ret )
973- return ret ;
974-
975- return WARN_ON (__do_share (share ));
976- }
977-
978- static int check_unshare (struct pkvm_mem_share * share )
979- {
980- const struct pkvm_mem_transition * tx = & share -> tx ;
981- u64 completer_addr ;
982- int ret ;
983-
984- switch (tx -> initiator .id ) {
985- case PKVM_ID_HOST :
986- ret = host_request_unshare (& completer_addr , tx );
987- break ;
988- default :
989- ret = - EINVAL ;
990- }
991-
992- if (ret )
993- return ret ;
994-
995- switch (tx -> completer .id ) {
996- case PKVM_ID_HYP :
997- ret = hyp_ack_unshare (completer_addr , tx );
998- break ;
999- case PKVM_ID_FFA :
1000- /* See check_share() */
1001- ret = 0 ;
1002- break ;
1003- default :
1004- ret = - EINVAL ;
1005- }
1006-
1007- return ret ;
1008- }
1009-
1010- static int __do_unshare (struct pkvm_mem_share * share )
1011- {
1012- const struct pkvm_mem_transition * tx = & share -> tx ;
1013- u64 completer_addr ;
1014- int ret ;
1015-
1016- switch (tx -> initiator .id ) {
1017- case PKVM_ID_HOST :
1018- ret = host_initiate_unshare (& completer_addr , tx );
1019- break ;
1020- default :
1021- ret = - EINVAL ;
1022- }
1023-
1024- if (ret )
1025- return ret ;
1026-
1027- switch (tx -> completer .id ) {
1028- case PKVM_ID_HYP :
1029- ret = hyp_complete_unshare (completer_addr , tx );
1030- break ;
1031- case PKVM_ID_FFA :
1032- /* See __do_share() */
1033- ret = 0 ;
1034- break ;
1035- default :
1036- ret = - EINVAL ;
1037- }
1038-
1039- return ret ;
1040- }
1041-
1042- /*
1043- * do_unshare():
1044- *
1045- * The page owner revokes access from another component for a range of
1046- * pages which were previously shared using do_share().
1047- *
1048- * Initiator: SHARED_OWNED => OWNED
1049- * Completer: SHARED_BORROWED => NOPAGE
1050- */
1051- static int do_unshare (struct pkvm_mem_share * share )
1052- {
1053- int ret ;
1054-
1055- ret = check_unshare (share );
1056- if (ret )
1057- return ret ;
1058-
1059- return WARN_ON (__do_unshare (share ));
1060- }
1061-
1062815static int check_donation (struct pkvm_mem_donation * donation )
1063816{
1064817 const struct pkvm_mem_transition * tx = & donation -> tx ;
@@ -1149,31 +902,29 @@ static int do_donate(struct pkvm_mem_donation *donation)
1149902
1150903int __pkvm_host_share_hyp (u64 pfn )
1151904{
905+ u64 phys = hyp_pfn_to_phys (pfn );
906+ void * virt = __hyp_va (phys );
907+ enum kvm_pgtable_prot prot ;
908+ u64 size = PAGE_SIZE ;
1152909 int ret ;
1153- u64 host_addr = hyp_pfn_to_phys (pfn );
1154- u64 hyp_addr = (u64 )__hyp_va (host_addr );
1155- struct pkvm_mem_share share = {
1156- .tx = {
1157- .nr_pages = 1 ,
1158- .initiator = {
1159- .id = PKVM_ID_HOST ,
1160- .addr = host_addr ,
1161- .host = {
1162- .completer_addr = hyp_addr ,
1163- },
1164- },
1165- .completer = {
1166- .id = PKVM_ID_HYP ,
1167- },
1168- },
1169- .completer_prot = PAGE_HYP ,
1170- };
1171910
1172911 host_lock_component ();
1173912 hyp_lock_component ();
1174913
1175- ret = do_share (& share );
914+ ret = __host_check_page_state_range (phys , size , PKVM_PAGE_OWNED );
915+ if (ret )
916+ goto unlock ;
917+ if (IS_ENABLED (CONFIG_NVHE_EL2_DEBUG )) {
918+ ret = __hyp_check_page_state_range ((u64 )virt , size , PKVM_NOPAGE );
919+ if (ret )
920+ goto unlock ;
921+ }
922+
923+ prot = pkvm_mkstate (PAGE_HYP , PKVM_PAGE_SHARED_BORROWED );
924+ WARN_ON (pkvm_create_mappings_locked (virt , virt + size , prot ));
925+ WARN_ON (__host_set_page_state_range (phys , size , PKVM_PAGE_SHARED_OWNED ));
1176926
927+ unlock :
1177928 hyp_unlock_component ();
1178929 host_unlock_component ();
1179930
@@ -1182,31 +933,29 @@ int __pkvm_host_share_hyp(u64 pfn)
1182933
1183934int __pkvm_host_unshare_hyp (u64 pfn )
1184935{
936+ u64 phys = hyp_pfn_to_phys (pfn );
937+ u64 virt = (u64 )__hyp_va (phys );
938+ u64 size = PAGE_SIZE ;
1185939 int ret ;
1186- u64 host_addr = hyp_pfn_to_phys (pfn );
1187- u64 hyp_addr = (u64 )__hyp_va (host_addr );
1188- struct pkvm_mem_share share = {
1189- .tx = {
1190- .nr_pages = 1 ,
1191- .initiator = {
1192- .id = PKVM_ID_HOST ,
1193- .addr = host_addr ,
1194- .host = {
1195- .completer_addr = hyp_addr ,
1196- },
1197- },
1198- .completer = {
1199- .id = PKVM_ID_HYP ,
1200- },
1201- },
1202- .completer_prot = PAGE_HYP ,
1203- };
1204940
1205941 host_lock_component ();
1206942 hyp_lock_component ();
1207943
1208- ret = do_unshare (& share );
944+ ret = __host_check_page_state_range (phys , size , PKVM_PAGE_SHARED_OWNED );
945+ if (ret )
946+ goto unlock ;
947+ ret = __hyp_check_page_state_range (virt , size , PKVM_PAGE_SHARED_BORROWED );
948+ if (ret )
949+ goto unlock ;
950+ if (hyp_page_count ((void * )virt )) {
951+ ret = - EBUSY ;
952+ goto unlock ;
953+ }
954+
955+ WARN_ON (kvm_pgtable_hyp_unmap (& pkvm_pgtable , virt , size ) != size );
956+ WARN_ON (__host_set_page_state_range (phys , size , PKVM_PAGE_OWNED ));
1209957
958+ unlock :
1210959 hyp_unlock_component ();
1211960 host_unlock_component ();
1212961
0 commit comments