@@ -685,36 +685,6 @@ static int host_request_owned_transition(u64 *completer_addr,
685
685
return __host_check_page_state_range (addr , size , PKVM_PAGE_OWNED );
686
686
}
687
687
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
-
718
688
static int host_initiate_donation (u64 * completer_addr ,
719
689
const struct pkvm_mem_transition * tx )
720
690
{
@@ -802,31 +772,6 @@ static bool __hyp_ack_skip_pgtable_check(const struct pkvm_mem_transition *tx)
802
772
tx -> initiator .id != PKVM_ID_HOST );
803
773
}
804
774
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
-
830
775
static int hyp_ack_donation (u64 addr , const struct pkvm_mem_transition * tx )
831
776
{
832
777
u64 size = tx -> nr_pages * PAGE_SIZE ;
@@ -837,24 +782,6 @@ static int hyp_ack_donation(u64 addr, const struct pkvm_mem_transition *tx)
837
782
return __hyp_check_page_state_range (addr , size , PKVM_NOPAGE );
838
783
}
839
784
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
-
858
785
static int hyp_complete_donation (u64 addr ,
859
786
const struct pkvm_mem_transition * tx )
860
787
{
@@ -885,180 +812,6 @@ static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
885
812
return check_page_state_range (& vm -> pgt , addr , size , & d );
886
813
}
887
814
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
-
1062
815
static int check_donation (struct pkvm_mem_donation * donation )
1063
816
{
1064
817
const struct pkvm_mem_transition * tx = & donation -> tx ;
@@ -1149,31 +902,29 @@ static int do_donate(struct pkvm_mem_donation *donation)
1149
902
1150
903
int __pkvm_host_share_hyp (u64 pfn )
1151
904
{
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 ;
1152
909
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
- };
1171
910
1172
911
host_lock_component ();
1173
912
hyp_lock_component ();
1174
913
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 ));
1176
926
927
+ unlock :
1177
928
hyp_unlock_component ();
1178
929
host_unlock_component ();
1179
930
@@ -1182,31 +933,29 @@ int __pkvm_host_share_hyp(u64 pfn)
1182
933
1183
934
int __pkvm_host_unshare_hyp (u64 pfn )
1184
935
{
936
+ u64 phys = hyp_pfn_to_phys (pfn );
937
+ u64 virt = (u64 )__hyp_va (phys );
938
+ u64 size = PAGE_SIZE ;
1185
939
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
- };
1204
940
1205
941
host_lock_component ();
1206
942
hyp_lock_component ();
1207
943
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 ));
1209
957
958
+ unlock :
1210
959
hyp_unlock_component ();
1211
960
host_unlock_component ();
1212
961
0 commit comments