@@ -864,21 +864,24 @@ static struct kvm_memory_slot *gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu
864
864
static int pte_list_add (struct kvm_mmu_memory_cache * cache , u64 * spte ,
865
865
struct kvm_rmap_head * rmap_head )
866
866
{
867
+ unsigned long old_val , new_val ;
867
868
struct pte_list_desc * desc ;
868
869
int count = 0 ;
869
870
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 )) {
873
876
desc = kvm_mmu_memory_cache_alloc (cache );
874
- desc -> sptes [0 ] = (u64 * )rmap_head -> val ;
877
+ desc -> sptes [0 ] = (u64 * )old_val ;
875
878
desc -> sptes [1 ] = spte ;
876
879
desc -> spte_count = 2 ;
877
880
desc -> tail_count = 0 ;
878
- rmap_head -> val = (unsigned long )desc | KVM_RMAP_MANY ;
881
+ new_val = (unsigned long )desc | KVM_RMAP_MANY ;
879
882
++ count ;
880
883
} else {
881
- desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
884
+ desc = (struct pte_list_desc * )(old_val & ~KVM_RMAP_MANY );
882
885
count = desc -> tail_count + desc -> spte_count ;
883
886
884
887
/*
@@ -887,21 +890,25 @@ static int pte_list_add(struct kvm_mmu_memory_cache *cache, u64 *spte,
887
890
*/
888
891
if (desc -> spte_count == PTE_LIST_EXT ) {
889
892
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 );
891
894
desc -> spte_count = 0 ;
892
895
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 ;
894
899
}
895
900
desc -> sptes [desc -> spte_count ++ ] = spte ;
896
901
}
902
+
903
+ rmap_head -> val = new_val ;
904
+
897
905
return count ;
898
906
}
899
907
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 ,
902
909
struct pte_list_desc * desc , int i )
903
910
{
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 );
905
912
int j = head_desc -> spte_count - 1 ;
906
913
907
914
/*
@@ -928,41 +935,46 @@ static void pte_list_desc_remove_entry(struct kvm *kvm,
928
935
* head at the next descriptor, i.e. the new head.
929
936
*/
930
937
if (!head_desc -> more )
931
- rmap_head -> val = 0 ;
938
+ * rmap_val = 0 ;
932
939
else
933
- rmap_head -> val = (unsigned long )head_desc -> more | KVM_RMAP_MANY ;
940
+ * rmap_val = (unsigned long )head_desc -> more | KVM_RMAP_MANY ;
934
941
mmu_free_pte_list_desc (head_desc );
935
942
}
936
943
937
944
static void pte_list_remove (struct kvm * kvm , u64 * spte ,
938
945
struct kvm_rmap_head * rmap_head )
939
946
{
940
947
struct pte_list_desc * desc ;
948
+ unsigned long rmap_val ;
941
949
int i ;
942
950
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 ;
945
954
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 ;
949
958
950
- rmap_head -> val = 0 ;
959
+ rmap_val = 0 ;
951
960
} else {
952
- desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
961
+ desc = (struct pte_list_desc * )(rmap_val & ~KVM_RMAP_MANY );
953
962
while (desc ) {
954
963
for (i = 0 ; i < desc -> spte_count ; ++ i ) {
955
964
if (desc -> sptes [i ] == spte ) {
956
- pte_list_desc_remove_entry (kvm , rmap_head ,
965
+ pte_list_desc_remove_entry (kvm , & rmap_val ,
957
966
desc , i );
958
- return ;
967
+ goto out ;
959
968
}
960
969
}
961
970
desc = desc -> more ;
962
971
}
963
972
964
973
KVM_BUG_ON_DATA_CORRUPTION (true, kvm );
965
974
}
975
+
976
+ out :
977
+ rmap_head -> val = rmap_val ;
966
978
}
967
979
968
980
static void kvm_zap_one_rmap_spte (struct kvm * kvm ,
@@ -977,17 +989,19 @@ static bool kvm_zap_all_rmap_sptes(struct kvm *kvm,
977
989
struct kvm_rmap_head * rmap_head )
978
990
{
979
991
struct pte_list_desc * desc , * next ;
992
+ unsigned long rmap_val ;
980
993
int i ;
981
994
982
- if (!rmap_head -> val )
995
+ rmap_val = rmap_head -> val ;
996
+ if (!rmap_val )
983
997
return false;
984
998
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 );
987
1001
goto out ;
988
1002
}
989
1003
990
- desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
1004
+ desc = (struct pte_list_desc * )(rmap_val & ~KVM_RMAP_MANY );
991
1005
992
1006
for (; desc ; desc = next ) {
993
1007
for (i = 0 ; i < desc -> spte_count ; i ++ )
@@ -1003,14 +1017,15 @@ static bool kvm_zap_all_rmap_sptes(struct kvm *kvm,
1003
1017
1004
1018
unsigned int pte_list_count (struct kvm_rmap_head * rmap_head )
1005
1019
{
1020
+ unsigned long rmap_val = rmap_head -> val ;
1006
1021
struct pte_list_desc * desc ;
1007
1022
1008
- if (!rmap_head -> val )
1023
+ if (!rmap_val )
1009
1024
return 0 ;
1010
- else if (!(rmap_head -> val & KVM_RMAP_MANY ))
1025
+ else if (!(rmap_val & KVM_RMAP_MANY ))
1011
1026
return 1 ;
1012
1027
1013
- desc = (struct pte_list_desc * )(rmap_head -> val & ~KVM_RMAP_MANY );
1028
+ desc = (struct pte_list_desc * )(rmap_val & ~KVM_RMAP_MANY );
1014
1029
return desc -> tail_count + desc -> spte_count ;
1015
1030
}
1016
1031
@@ -1053,6 +1068,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
1053
1068
*/
1054
1069
struct rmap_iterator {
1055
1070
/* private fields */
1071
+ struct rmap_head * head ;
1056
1072
struct pte_list_desc * desc ; /* holds the sptep if not NULL */
1057
1073
int pos ; /* index of the sptep */
1058
1074
};
@@ -1067,18 +1083,19 @@ struct rmap_iterator {
1067
1083
static u64 * rmap_get_first (struct kvm_rmap_head * rmap_head ,
1068
1084
struct rmap_iterator * iter )
1069
1085
{
1086
+ unsigned long rmap_val = rmap_head -> val ;
1070
1087
u64 * sptep ;
1071
1088
1072
- if (!rmap_head -> val )
1089
+ if (!rmap_val )
1073
1090
return NULL ;
1074
1091
1075
- if (!(rmap_head -> val & KVM_RMAP_MANY )) {
1092
+ if (!(rmap_val & KVM_RMAP_MANY )) {
1076
1093
iter -> desc = NULL ;
1077
- sptep = (u64 * )rmap_head -> val ;
1094
+ sptep = (u64 * )rmap_val ;
1078
1095
goto out ;
1079
1096
}
1080
1097
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 );
1082
1099
iter -> pos = 0 ;
1083
1100
sptep = iter -> desc -> sptes [iter -> pos ];
1084
1101
out :
0 commit comments