@@ -649,24 +649,24 @@ static int __host_set_page_state_range(u64 addr, u64 size,
649
649
return 0 ;
650
650
}
651
651
652
- static enum pkvm_page_state hyp_get_page_state ( kvm_pte_t pte , u64 addr )
652
+ static void __hyp_set_page_state_range ( phys_addr_t phys , u64 size , enum pkvm_page_state state )
653
653
{
654
- if (!kvm_pte_valid (pte ))
655
- return PKVM_NOPAGE ;
654
+ phys_addr_t end = phys + size ;
656
655
657
- return pkvm_getstate (kvm_pgtable_hyp_pte_prot (pte ));
656
+ for (; phys < end ; phys += PAGE_SIZE )
657
+ set_hyp_state (phys , state );
658
658
}
659
659
660
- static int __hyp_check_page_state_range (u64 addr , u64 size ,
661
- enum pkvm_page_state state )
660
+ static int __hyp_check_page_state_range (phys_addr_t phys , u64 size , enum pkvm_page_state state )
662
661
{
663
- struct check_walk_data d = {
664
- .desired = state ,
665
- .get_page_state = hyp_get_page_state ,
666
- };
662
+ phys_addr_t end = phys + size ;
663
+
664
+ for (; phys < end ; phys += PAGE_SIZE ) {
665
+ if (get_hyp_state (phys ) != state )
666
+ return - EPERM ;
667
+ }
667
668
668
- hyp_assert_lock_held (& pkvm_pgd_lock );
669
- return check_page_state_range (& pkvm_pgtable , addr , size , & d );
669
+ return 0 ;
670
670
}
671
671
672
672
static enum pkvm_page_state guest_get_page_state (kvm_pte_t pte , u64 addr )
@@ -694,7 +694,6 @@ int __pkvm_host_share_hyp(u64 pfn)
694
694
{
695
695
u64 phys = hyp_pfn_to_phys (pfn );
696
696
void * virt = __hyp_va (phys );
697
- enum kvm_pgtable_prot prot ;
698
697
u64 size = PAGE_SIZE ;
699
698
int ret ;
700
699
@@ -705,13 +704,13 @@ int __pkvm_host_share_hyp(u64 pfn)
705
704
if (ret )
706
705
goto unlock ;
707
706
if (IS_ENABLED (CONFIG_NVHE_EL2_DEBUG )) {
708
- ret = __hyp_check_page_state_range (( u64 ) virt , size , PKVM_NOPAGE );
707
+ ret = __hyp_check_page_state_range (phys , size , PKVM_NOPAGE );
709
708
if (ret )
710
709
goto unlock ;
711
710
}
712
711
713
- prot = pkvm_mkstate ( PAGE_HYP , PKVM_PAGE_SHARED_BORROWED );
714
- WARN_ON (pkvm_create_mappings_locked (virt , virt + size , prot ));
712
+ __hyp_set_page_state_range ( phys , size , PKVM_PAGE_SHARED_BORROWED );
713
+ WARN_ON (pkvm_create_mappings_locked (virt , virt + size , PAGE_HYP ));
715
714
WARN_ON (__host_set_page_state_range (phys , size , PKVM_PAGE_SHARED_OWNED ));
716
715
717
716
unlock :
@@ -734,14 +733,15 @@ int __pkvm_host_unshare_hyp(u64 pfn)
734
733
ret = __host_check_page_state_range (phys , size , PKVM_PAGE_SHARED_OWNED );
735
734
if (ret )
736
735
goto unlock ;
737
- ret = __hyp_check_page_state_range (virt , size , PKVM_PAGE_SHARED_BORROWED );
736
+ ret = __hyp_check_page_state_range (phys , size , PKVM_PAGE_SHARED_BORROWED );
738
737
if (ret )
739
738
goto unlock ;
740
739
if (hyp_page_count ((void * )virt )) {
741
740
ret = - EBUSY ;
742
741
goto unlock ;
743
742
}
744
743
744
+ __hyp_set_page_state_range (phys , size , PKVM_NOPAGE );
745
745
WARN_ON (kvm_pgtable_hyp_unmap (& pkvm_pgtable , virt , size ) != size );
746
746
WARN_ON (__host_set_page_state_range (phys , size , PKVM_PAGE_OWNED ));
747
747
@@ -757,7 +757,6 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages)
757
757
u64 phys = hyp_pfn_to_phys (pfn );
758
758
u64 size = PAGE_SIZE * nr_pages ;
759
759
void * virt = __hyp_va (phys );
760
- enum kvm_pgtable_prot prot ;
761
760
int ret ;
762
761
763
762
host_lock_component ();
@@ -767,13 +766,13 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages)
767
766
if (ret )
768
767
goto unlock ;
769
768
if (IS_ENABLED (CONFIG_NVHE_EL2_DEBUG )) {
770
- ret = __hyp_check_page_state_range (( u64 ) virt , size , PKVM_NOPAGE );
769
+ ret = __hyp_check_page_state_range (phys , size , PKVM_NOPAGE );
771
770
if (ret )
772
771
goto unlock ;
773
772
}
774
773
775
- prot = pkvm_mkstate ( PAGE_HYP , PKVM_PAGE_OWNED );
776
- WARN_ON (pkvm_create_mappings_locked (virt , virt + size , prot ));
774
+ __hyp_set_page_state_range ( phys , size , PKVM_PAGE_OWNED );
775
+ WARN_ON (pkvm_create_mappings_locked (virt , virt + size , PAGE_HYP ));
777
776
WARN_ON (host_stage2_set_owner_locked (phys , size , PKVM_ID_HYP ));
778
777
779
778
unlock :
@@ -793,7 +792,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages)
793
792
host_lock_component ();
794
793
hyp_lock_component ();
795
794
796
- ret = __hyp_check_page_state_range (virt , size , PKVM_PAGE_OWNED );
795
+ ret = __hyp_check_page_state_range (phys , size , PKVM_PAGE_OWNED );
797
796
if (ret )
798
797
goto unlock ;
799
798
if (IS_ENABLED (CONFIG_NVHE_EL2_DEBUG )) {
@@ -802,6 +801,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages)
802
801
goto unlock ;
803
802
}
804
803
804
+ __hyp_set_page_state_range (phys , size , PKVM_NOPAGE );
805
805
WARN_ON (kvm_pgtable_hyp_unmap (& pkvm_pgtable , virt , size ) != size );
806
806
WARN_ON (host_stage2_set_owner_locked (phys , size , PKVM_ID_HOST ));
807
807
@@ -816,19 +816,18 @@ int hyp_pin_shared_mem(void *from, void *to)
816
816
{
817
817
u64 cur , start = ALIGN_DOWN ((u64 )from , PAGE_SIZE );
818
818
u64 end = PAGE_ALIGN ((u64 )to );
819
+ u64 phys = __hyp_pa (start );
819
820
u64 size = end - start ;
820
821
int ret ;
821
822
822
823
host_lock_component ();
823
824
hyp_lock_component ();
824
825
825
- ret = __host_check_page_state_range (__hyp_pa (start ), size ,
826
- PKVM_PAGE_SHARED_OWNED );
826
+ ret = __host_check_page_state_range (phys , size , PKVM_PAGE_SHARED_OWNED );
827
827
if (ret )
828
828
goto unlock ;
829
829
830
- ret = __hyp_check_page_state_range (start , size ,
831
- PKVM_PAGE_SHARED_BORROWED );
830
+ ret = __hyp_check_page_state_range (phys , size , PKVM_PAGE_SHARED_BORROWED );
832
831
if (ret )
833
832
goto unlock ;
834
833
0 commit comments