@@ -864,21 +864,24 @@ static struct kvm_memory_slot *gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu
864864static int pte_list_add (struct kvm_mmu_memory_cache * cache , u64 * spte ,
865865 struct kvm_rmap_head * rmap_head )
866866{
867+ unsigned long old_val , new_val ;
867868 struct pte_list_desc * desc ;
868869 int count = 0 ;
869870
870- if (!rmap_head -> val ) {
871- rmap_head -> val = (unsigned long )spte ;
872- } else if (!(rmap_head -> val & KVM_RMAP_MANY )) {
871+ old_val = rmap_head -> val ;
872+
873+ if (!old_val ) {
874+ new_val = (unsigned long )spte ;
875+ } else if (!(old_val & KVM_RMAP_MANY )) {
873876 desc = kvm_mmu_memory_cache_alloc (cache );
874- desc -> sptes [0 ] = (u64 * )rmap_head -> val ;
877+ desc -> sptes [0 ] = (u64 * )old_val ;
875878 desc -> sptes [1 ] = spte ;
876879 desc -> spte_count = 2 ;
877880 desc -> tail_count = 0 ;
878- rmap_head -> val = (unsigned long )desc | KVM_RMAP_MANY ;
881+ new_val = (unsigned long )desc | KVM_RMAP_MANY ;
879882 ++ count ;
880883 } else {
881- desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
884+ desc = (struct pte_list_desc * )(old_val & ~KVM_RMAP_MANY );
882885 count = desc -> tail_count + desc -> spte_count ;
883886
884887 /*
@@ -887,21 +890,25 @@ static int pte_list_add(struct kvm_mmu_memory_cache *cache, u64 *spte,
887890 */
888891 if (desc -> spte_count == PTE_LIST_EXT ) {
889892 desc = kvm_mmu_memory_cache_alloc (cache );
890- desc -> more = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
893+ desc -> more = (struct pte_list_desc * )(old_val & ~KVM_RMAP_MANY );
891894 desc -> spte_count = 0 ;
892895 desc -> tail_count = count ;
893- rmap_head -> val = (unsigned long )desc | KVM_RMAP_MANY ;
896+ new_val = (unsigned long )desc | KVM_RMAP_MANY ;
897+ } else {
898+ new_val = old_val ;
894899 }
895900 desc -> sptes [desc -> spte_count ++ ] = spte ;
896901 }
902+
903+ rmap_head -> val = new_val ;
904+
897905 return count ;
898906}
899907
900- static void pte_list_desc_remove_entry (struct kvm * kvm ,
901- struct kvm_rmap_head * rmap_head ,
908+ static void pte_list_desc_remove_entry (struct kvm * kvm , unsigned long * rmap_val ,
902909 struct pte_list_desc * desc , int i )
903910{
904- struct pte_list_desc * head_desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
911+ struct pte_list_desc * head_desc = (struct pte_list_desc * )(* rmap_val & ~KVM_RMAP_MANY );
905912 int j = head_desc -> spte_count - 1 ;
906913
907914 /*
@@ -928,41 +935,46 @@ static void pte_list_desc_remove_entry(struct kvm *kvm,
928935 * head at the next descriptor, i.e. the new head.
929936 */
930937 if (!head_desc -> more )
931- rmap_head -> val = 0 ;
938+ * rmap_val = 0 ;
932939 else
933- rmap_head -> val = (unsigned long )head_desc -> more | KVM_RMAP_MANY ;
940+ * rmap_val = (unsigned long )head_desc -> more | KVM_RMAP_MANY ;
934941 mmu_free_pte_list_desc (head_desc );
935942}
936943
937944static void pte_list_remove (struct kvm * kvm , u64 * spte ,
938945 struct kvm_rmap_head * rmap_head )
939946{
940947 struct pte_list_desc * desc ;
948+ unsigned long rmap_val ;
941949 int i ;
942950
943- if (KVM_BUG_ON_DATA_CORRUPTION (!rmap_head -> val , kvm ))
944- return ;
951+ rmap_val = rmap_head -> val ;
952+ if (KVM_BUG_ON_DATA_CORRUPTION (!rmap_val , kvm ))
953+ goto out ;
945954
946- if (!(rmap_head -> val & KVM_RMAP_MANY )) {
947- if (KVM_BUG_ON_DATA_CORRUPTION ((u64 * )rmap_head -> val != spte , kvm ))
948- return ;
955+ if (!(rmap_val & KVM_RMAP_MANY )) {
956+ if (KVM_BUG_ON_DATA_CORRUPTION ((u64 * )rmap_val != spte , kvm ))
957+ goto out ;
949958
950- rmap_head -> val = 0 ;
959+ rmap_val = 0 ;
951960 } else {
952- desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
961+ desc = (struct pte_list_desc * )(rmap_val & ~KVM_RMAP_MANY );
953962 while (desc ) {
954963 for (i = 0 ; i < desc -> spte_count ; ++ i ) {
955964 if (desc -> sptes [i ] == spte ) {
956- pte_list_desc_remove_entry (kvm , rmap_head ,
965+ pte_list_desc_remove_entry (kvm , & rmap_val ,
957966 desc , i );
958- return ;
967+ goto out ;
959968 }
960969 }
961970 desc = desc -> more ;
962971 }
963972
964973 KVM_BUG_ON_DATA_CORRUPTION (true, kvm );
965974 }
975+
976+ out :
977+ rmap_head -> val = rmap_val ;
966978}
967979
968980static void kvm_zap_one_rmap_spte (struct kvm * kvm ,
@@ -977,17 +989,19 @@ static bool kvm_zap_all_rmap_sptes(struct kvm *kvm,
977989 struct kvm_rmap_head * rmap_head )
978990{
979991 struct pte_list_desc * desc , * next ;
992+ unsigned long rmap_val ;
980993 int i ;
981994
982- if (!rmap_head -> val )
995+ rmap_val = rmap_head -> val ;
996+ if (!rmap_val )
983997 return false;
984998
985- if (!(rmap_head -> val & KVM_RMAP_MANY )) {
986- mmu_spte_clear_track_bits (kvm , (u64 * )rmap_head -> val );
999+ if (!(rmap_val & KVM_RMAP_MANY )) {
1000+ mmu_spte_clear_track_bits (kvm , (u64 * )rmap_val );
9871001 goto out ;
9881002 }
9891003
990- desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
1004+ desc = (struct pte_list_desc * )(rmap_val & ~KVM_RMAP_MANY );
9911005
9921006 for (; desc ; desc = next ) {
9931007 for (i = 0 ; i < desc -> spte_count ; i ++ )
@@ -1003,14 +1017,15 @@ static bool kvm_zap_all_rmap_sptes(struct kvm *kvm,
10031017
10041018unsigned int pte_list_count (struct kvm_rmap_head * rmap_head )
10051019{
1020+ unsigned long rmap_val = rmap_head -> val ;
10061021 struct pte_list_desc * desc ;
10071022
1008- if (!rmap_head -> val )
1023+ if (!rmap_val )
10091024 return 0 ;
1010- else if (!(rmap_head -> val & KVM_RMAP_MANY ))
1025+ else if (!(rmap_val & KVM_RMAP_MANY ))
10111026 return 1 ;
10121027
1013- desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
1028+ desc = (struct pte_list_desc * )(rmap_val & ~KVM_RMAP_MANY );
10141029 return desc -> tail_count + desc -> spte_count ;
10151030}
10161031
@@ -1053,6 +1068,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
10531068 */
10541069struct rmap_iterator {
10551070 /* private fields */
1071+ struct rmap_head * head ;
10561072 struct pte_list_desc * desc ; /* holds the sptep if not NULL */
10571073 int pos ; /* index of the sptep */
10581074};
@@ -1067,18 +1083,19 @@ struct rmap_iterator {
10671083static u64 * rmap_get_first (struct kvm_rmap_head * rmap_head ,
10681084 struct rmap_iterator * iter )
10691085{
1086+ unsigned long rmap_val = rmap_head -> val ;
10701087 u64 * sptep ;
10711088
1072- if (!rmap_head -> val )
1089+ if (!rmap_val )
10731090 return NULL ;
10741091
1075- if (!(rmap_head -> val & KVM_RMAP_MANY )) {
1092+ if (!(rmap_val & KVM_RMAP_MANY )) {
10761093 iter -> desc = NULL ;
1077- sptep = (u64 * )rmap_head -> val ;
1094+ sptep = (u64 * )rmap_val ;
10781095 goto out ;
10791096 }
10801097
1081- iter -> desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
1098+ iter -> desc = (struct pte_list_desc * )(rmap_val & ~KVM_RMAP_MANY );
10821099 iter -> pos = 0 ;
10831100 sptep = iter -> desc -> sptes [iter -> pos ];
10841101out :
0 commit comments