@@ -583,39 +583,6 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
583
583
BUG_ON (ret && ret != - EAGAIN );
584
584
}
585
585
586
- struct pkvm_mem_transition {
587
- u64 nr_pages ;
588
-
589
- struct {
590
- enum pkvm_component_id id ;
591
- /* Address in the initiator's address space */
592
- u64 addr ;
593
-
594
- union {
595
- struct {
596
- /* Address in the completer's address space */
597
- u64 completer_addr ;
598
- } host ;
599
- struct {
600
- u64 completer_addr ;
601
- } hyp ;
602
- };
603
- } initiator ;
604
-
605
- struct {
606
- enum pkvm_component_id id ;
607
- } completer ;
608
- };
609
-
610
- struct pkvm_mem_share {
611
- const struct pkvm_mem_transition tx ;
612
- const enum kvm_pgtable_prot completer_prot ;
613
- };
614
-
615
- struct pkvm_mem_donation {
616
- const struct pkvm_mem_transition tx ;
617
- };
618
-
619
586
struct check_walk_data {
620
587
enum pkvm_page_state desired ;
621
588
enum pkvm_page_state (* get_page_state )(kvm_pte_t pte , u64 addr );
@@ -675,56 +642,6 @@ static int __host_set_page_state_range(u64 addr, u64 size,
675
642
return 0 ;
676
643
}
677
644
678
- static int host_request_owned_transition (u64 * completer_addr ,
679
- const struct pkvm_mem_transition * tx )
680
- {
681
- u64 size = tx -> nr_pages * PAGE_SIZE ;
682
- u64 addr = tx -> initiator .addr ;
683
-
684
- * completer_addr = tx -> initiator .host .completer_addr ;
685
- return __host_check_page_state_range (addr , size , PKVM_PAGE_OWNED );
686
- }
687
-
688
- static int host_initiate_donation (u64 * completer_addr ,
689
- const struct pkvm_mem_transition * tx )
690
- {
691
- u8 owner_id = tx -> completer .id ;
692
- u64 size = tx -> nr_pages * PAGE_SIZE ;
693
-
694
- * completer_addr = tx -> initiator .host .completer_addr ;
695
- return host_stage2_set_owner_locked (tx -> initiator .addr , size , owner_id );
696
- }
697
-
698
- static bool __host_ack_skip_pgtable_check (const struct pkvm_mem_transition * tx )
699
- {
700
- return !(IS_ENABLED (CONFIG_NVHE_EL2_DEBUG ) ||
701
- tx -> initiator .id != PKVM_ID_HYP );
702
- }
703
-
704
- static int __host_ack_transition (u64 addr , const struct pkvm_mem_transition * tx ,
705
- enum pkvm_page_state state )
706
- {
707
- u64 size = tx -> nr_pages * PAGE_SIZE ;
708
-
709
- if (__host_ack_skip_pgtable_check (tx ))
710
- return 0 ;
711
-
712
- return __host_check_page_state_range (addr , size , state );
713
- }
714
-
715
- static int host_ack_donation (u64 addr , const struct pkvm_mem_transition * tx )
716
- {
717
- return __host_ack_transition (addr , tx , PKVM_NOPAGE );
718
- }
719
-
720
- static int host_complete_donation (u64 addr , const struct pkvm_mem_transition * tx )
721
- {
722
- u64 size = tx -> nr_pages * PAGE_SIZE ;
723
- u8 host_id = tx -> completer .id ;
724
-
725
- return host_stage2_set_owner_locked (addr , size , host_id );
726
- }
727
-
728
645
static enum pkvm_page_state hyp_get_page_state (kvm_pte_t pte , u64 addr )
729
646
{
730
647
if (!kvm_pte_valid (pte ))
@@ -745,52 +662,6 @@ static int __hyp_check_page_state_range(u64 addr, u64 size,
745
662
return check_page_state_range (& pkvm_pgtable , addr , size , & d );
746
663
}
747
664
748
- static int hyp_request_donation (u64 * completer_addr ,
749
- const struct pkvm_mem_transition * tx )
750
- {
751
- u64 size = tx -> nr_pages * PAGE_SIZE ;
752
- u64 addr = tx -> initiator .addr ;
753
-
754
- * completer_addr = tx -> initiator .hyp .completer_addr ;
755
- return __hyp_check_page_state_range (addr , size , PKVM_PAGE_OWNED );
756
- }
757
-
758
- static int hyp_initiate_donation (u64 * completer_addr ,
759
- const struct pkvm_mem_transition * tx )
760
- {
761
- u64 size = tx -> nr_pages * PAGE_SIZE ;
762
- int ret ;
763
-
764
- * completer_addr = tx -> initiator .hyp .completer_addr ;
765
- ret = kvm_pgtable_hyp_unmap (& pkvm_pgtable , tx -> initiator .addr , size );
766
- return (ret != size ) ? - EFAULT : 0 ;
767
- }
768
-
769
- static bool __hyp_ack_skip_pgtable_check (const struct pkvm_mem_transition * tx )
770
- {
771
- return !(IS_ENABLED (CONFIG_NVHE_EL2_DEBUG ) ||
772
- tx -> initiator .id != PKVM_ID_HOST );
773
- }
774
-
775
- static int hyp_ack_donation (u64 addr , const struct pkvm_mem_transition * tx )
776
- {
777
- u64 size = tx -> nr_pages * PAGE_SIZE ;
778
-
779
- if (__hyp_ack_skip_pgtable_check (tx ))
780
- return 0 ;
781
-
782
- return __hyp_check_page_state_range (addr , size , PKVM_NOPAGE );
783
- }
784
-
785
- static int hyp_complete_donation (u64 addr ,
786
- const struct pkvm_mem_transition * tx )
787
- {
788
- void * start = (void * )addr , * end = start + (tx -> nr_pages * PAGE_SIZE );
789
- enum kvm_pgtable_prot prot = pkvm_mkstate (PAGE_HYP , PKVM_PAGE_OWNED );
790
-
791
- return pkvm_create_mappings_locked (start , end , prot );
792
- }
793
-
794
665
static enum pkvm_page_state guest_get_page_state (kvm_pte_t pte , u64 addr )
795
666
{
796
667
if (!kvm_pte_valid (pte ))
@@ -812,94 +683,6 @@ static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
812
683
return check_page_state_range (& vm -> pgt , addr , size , & d );
813
684
}
814
685
815
- static int check_donation (struct pkvm_mem_donation * donation )
816
- {
817
- const struct pkvm_mem_transition * tx = & donation -> tx ;
818
- u64 completer_addr ;
819
- int ret ;
820
-
821
- switch (tx -> initiator .id ) {
822
- case PKVM_ID_HOST :
823
- ret = host_request_owned_transition (& completer_addr , tx );
824
- break ;
825
- case PKVM_ID_HYP :
826
- ret = hyp_request_donation (& completer_addr , tx );
827
- break ;
828
- default :
829
- ret = - EINVAL ;
830
- }
831
-
832
- if (ret )
833
- return ret ;
834
-
835
- switch (tx -> completer .id ) {
836
- case PKVM_ID_HOST :
837
- ret = host_ack_donation (completer_addr , tx );
838
- break ;
839
- case PKVM_ID_HYP :
840
- ret = hyp_ack_donation (completer_addr , tx );
841
- break ;
842
- default :
843
- ret = - EINVAL ;
844
- }
845
-
846
- return ret ;
847
- }
848
-
849
- static int __do_donate (struct pkvm_mem_donation * donation )
850
- {
851
- const struct pkvm_mem_transition * tx = & donation -> tx ;
852
- u64 completer_addr ;
853
- int ret ;
854
-
855
- switch (tx -> initiator .id ) {
856
- case PKVM_ID_HOST :
857
- ret = host_initiate_donation (& completer_addr , tx );
858
- break ;
859
- case PKVM_ID_HYP :
860
- ret = hyp_initiate_donation (& completer_addr , tx );
861
- break ;
862
- default :
863
- ret = - EINVAL ;
864
- }
865
-
866
- if (ret )
867
- return ret ;
868
-
869
- switch (tx -> completer .id ) {
870
- case PKVM_ID_HOST :
871
- ret = host_complete_donation (completer_addr , tx );
872
- break ;
873
- case PKVM_ID_HYP :
874
- ret = hyp_complete_donation (completer_addr , tx );
875
- break ;
876
- default :
877
- ret = - EINVAL ;
878
- }
879
-
880
- return ret ;
881
- }
882
-
883
- /*
884
- * do_donate():
885
- *
886
- * The page owner transfers ownership to another component, losing access
887
- * as a consequence.
888
- *
889
- * Initiator: OWNED => NOPAGE
890
- * Completer: NOPAGE => OWNED
891
- */
892
- static int do_donate (struct pkvm_mem_donation * donation )
893
- {
894
- int ret ;
895
-
896
- ret = check_donation (donation );
897
- if (ret )
898
- return ret ;
899
-
900
- return WARN_ON (__do_donate (donation ));
901
- }
902
-
903
686
int __pkvm_host_share_hyp (u64 pfn )
904
687
{
905
688
u64 phys = hyp_pfn_to_phys (pfn );
@@ -964,30 +747,29 @@ int __pkvm_host_unshare_hyp(u64 pfn)
964
747
965
748
int __pkvm_host_donate_hyp (u64 pfn , u64 nr_pages )
966
749
{
750
+ u64 phys = hyp_pfn_to_phys (pfn );
751
+ u64 size = PAGE_SIZE * nr_pages ;
752
+ void * virt = __hyp_va (phys );
753
+ enum kvm_pgtable_prot prot ;
967
754
int ret ;
968
- u64 host_addr = hyp_pfn_to_phys (pfn );
969
- u64 hyp_addr = (u64 )__hyp_va (host_addr );
970
- struct pkvm_mem_donation donation = {
971
- .tx = {
972
- .nr_pages = nr_pages ,
973
- .initiator = {
974
- .id = PKVM_ID_HOST ,
975
- .addr = host_addr ,
976
- .host = {
977
- .completer_addr = hyp_addr ,
978
- },
979
- },
980
- .completer = {
981
- .id = PKVM_ID_HYP ,
982
- },
983
- },
984
- };
985
755
986
756
host_lock_component ();
987
757
hyp_lock_component ();
988
758
989
- ret = do_donate (& donation );
759
+ ret = __host_check_page_state_range (phys , size , PKVM_PAGE_OWNED );
760
+ if (ret )
761
+ goto unlock ;
762
+ if (IS_ENABLED (CONFIG_NVHE_EL2_DEBUG )) {
763
+ ret = __hyp_check_page_state_range ((u64 )virt , size , PKVM_NOPAGE );
764
+ if (ret )
765
+ goto unlock ;
766
+ }
990
767
768
+ prot = pkvm_mkstate (PAGE_HYP , PKVM_PAGE_OWNED );
769
+ WARN_ON (pkvm_create_mappings_locked (virt , virt + size , prot ));
770
+ WARN_ON (host_stage2_set_owner_locked (phys , size , PKVM_ID_HYP ));
771
+
772
+ unlock :
991
773
hyp_unlock_component ();
992
774
host_unlock_component ();
993
775
@@ -996,30 +778,27 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages)
996
778
997
779
int __pkvm_hyp_donate_host (u64 pfn , u64 nr_pages )
998
780
{
781
+ u64 phys = hyp_pfn_to_phys (pfn );
782
+ u64 size = PAGE_SIZE * nr_pages ;
783
+ u64 virt = (u64 )__hyp_va (phys );
999
784
int ret ;
1000
- u64 host_addr = hyp_pfn_to_phys (pfn );
1001
- u64 hyp_addr = (u64 )__hyp_va (host_addr );
1002
- struct pkvm_mem_donation donation = {
1003
- .tx = {
1004
- .nr_pages = nr_pages ,
1005
- .initiator = {
1006
- .id = PKVM_ID_HYP ,
1007
- .addr = hyp_addr ,
1008
- .hyp = {
1009
- .completer_addr = host_addr ,
1010
- },
1011
- },
1012
- .completer = {
1013
- .id = PKVM_ID_HOST ,
1014
- },
1015
- },
1016
- };
1017
785
1018
786
host_lock_component ();
1019
787
hyp_lock_component ();
1020
788
1021
- ret = do_donate (& donation );
789
+ ret = __hyp_check_page_state_range (virt , size , PKVM_PAGE_OWNED );
790
+ if (ret )
791
+ goto unlock ;
792
+ if (IS_ENABLED (CONFIG_NVHE_EL2_DEBUG )) {
793
+ ret = __host_check_page_state_range (phys , size , PKVM_NOPAGE );
794
+ if (ret )
795
+ goto unlock ;
796
+ }
1022
797
798
+ WARN_ON (kvm_pgtable_hyp_unmap (& pkvm_pgtable , virt , size ) != size );
799
+ WARN_ON (host_stage2_set_owner_locked (phys , size , PKVM_ID_HOST ));
800
+
801
+ unlock :
1023
802
hyp_unlock_component ();
1024
803
host_unlock_component ();
1025
804
0 commit comments