@@ -983,6 +983,66 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm,
983
983
return old_memslots ;
984
984
}
985
985
986
+ static int kvm_set_memslot (struct kvm * kvm ,
987
+ const struct kvm_userspace_memory_region * mem ,
988
+ const struct kvm_memory_slot * old ,
989
+ struct kvm_memory_slot * new , int as_id ,
990
+ enum kvm_mr_change change )
991
+ {
992
+ struct kvm_memory_slot * slot ;
993
+ struct kvm_memslots * slots ;
994
+ int r ;
995
+
996
+ slots = kvzalloc (sizeof (struct kvm_memslots ), GFP_KERNEL_ACCOUNT );
997
+ if (!slots )
998
+ return - ENOMEM ;
999
+ memcpy (slots , __kvm_memslots (kvm , as_id ), sizeof (struct kvm_memslots ));
1000
+
1001
+ if (change == KVM_MR_DELETE || change == KVM_MR_MOVE ) {
1002
+ /*
1003
+ * Note, the INVALID flag needs to be in the appropriate entry
1004
+ * in the freshly allocated memslots, not in @old or @new.
1005
+ */
1006
+ slot = id_to_memslot (slots , old -> id );
1007
+ slot -> flags |= KVM_MEMSLOT_INVALID ;
1008
+
1009
+ /*
1010
+ * We can re-use the old memslots, the only difference from the
1011
+ * newly installed memslots is the invalid flag, which will get
1012
+ * dropped by update_memslots anyway. We'll also revert to the
1013
+ * old memslots if preparing the new memory region fails.
1014
+ */
1015
+ slots = install_new_memslots (kvm , as_id , slots );
1016
+
1017
+ /* From this point no new shadow pages pointing to a deleted,
1018
+ * or moved, memslot will be created.
1019
+ *
1020
+ * validation of sp->gfn happens in:
1021
+ * - gfn_to_hva (kvm_read_guest, gfn_to_pfn)
1022
+ * - kvm_is_visible_gfn (mmu_check_root)
1023
+ */
1024
+ kvm_arch_flush_shadow_memslot (kvm , slot );
1025
+ }
1026
+
1027
+ r = kvm_arch_prepare_memory_region (kvm , new , mem , change );
1028
+ if (r )
1029
+ goto out_slots ;
1030
+
1031
+ update_memslots (slots , new , change );
1032
+ slots = install_new_memslots (kvm , as_id , slots );
1033
+
1034
+ kvm_arch_commit_memory_region (kvm , mem , old , new , change );
1035
+
1036
+ kvfree (slots );
1037
+ return 0 ;
1038
+
1039
+ out_slots :
1040
+ if (change == KVM_MR_DELETE || change == KVM_MR_MOVE )
1041
+ slots = install_new_memslots (kvm , as_id , slots );
1042
+ kvfree (slots );
1043
+ return r ;
1044
+ }
1045
+
986
1046
/*
987
1047
* Allocate some memory and give it an address in the guest physical address
988
1048
* space.
@@ -999,7 +1059,6 @@ int __kvm_set_memory_region(struct kvm *kvm,
999
1059
unsigned long npages ;
1000
1060
struct kvm_memory_slot * slot ;
1001
1061
struct kvm_memory_slot old , new ;
1002
- struct kvm_memslots * slots ;
1003
1062
int as_id , id ;
1004
1063
enum kvm_mr_change change ;
1005
1064
@@ -1086,58 +1145,19 @@ int __kvm_set_memory_region(struct kvm *kvm,
1086
1145
return r ;
1087
1146
}
1088
1147
1089
- slots = kvzalloc (sizeof (struct kvm_memslots ), GFP_KERNEL_ACCOUNT );
1090
- if (!slots ) {
1091
- r = - ENOMEM ;
1092
- goto out_bitmap ;
1093
- }
1094
- memcpy (slots , __kvm_memslots (kvm , as_id ), sizeof (struct kvm_memslots ));
1095
-
1096
- if ((change == KVM_MR_DELETE ) || (change == KVM_MR_MOVE )) {
1097
- slot = id_to_memslot (slots , id );
1098
- slot -> flags |= KVM_MEMSLOT_INVALID ;
1099
-
1100
- /*
1101
- * We can re-use the old memslots, the only difference from the
1102
- * newly installed memslots is the invalid flag, which will get
1103
- * dropped by update_memslots anyway. We'll also revert to the
1104
- * old memslots if preparing the new memory region fails.
1105
- */
1106
- slots = install_new_memslots (kvm , as_id , slots );
1107
-
1108
- /* From this point no new shadow pages pointing to a deleted,
1109
- * or moved, memslot will be created.
1110
- *
1111
- * validation of sp->gfn happens in:
1112
- * - gfn_to_hva (kvm_read_guest, gfn_to_pfn)
1113
- * - kvm_is_visible_gfn (mmu_check_root)
1114
- */
1115
- kvm_arch_flush_shadow_memslot (kvm , slot );
1116
- }
1117
-
1118
- r = kvm_arch_prepare_memory_region (kvm , & new , mem , change );
1119
- if (r )
1120
- goto out_slots ;
1121
-
1122
1148
/* actual memory is freed via old in kvm_free_memslot below */
1123
1149
if (change == KVM_MR_DELETE ) {
1124
1150
new .dirty_bitmap = NULL ;
1125
1151
memset (& new .arch , 0 , sizeof (new .arch ));
1126
1152
}
1127
1153
1128
- update_memslots (slots , & new , change );
1129
- slots = install_new_memslots (kvm , as_id , slots );
1130
-
1131
- kvm_arch_commit_memory_region (kvm , mem , & old , & new , change );
1154
+ r = kvm_set_memslot (kvm , mem , & old , & new , as_id , change );
1155
+ if (r )
1156
+ goto out_bitmap ;
1132
1157
1133
1158
kvm_free_memslot (kvm , & old , & new );
1134
- kvfree (slots );
1135
1159
return 0 ;
1136
1160
1137
- out_slots :
1138
- if (change == KVM_MR_DELETE || change == KVM_MR_MOVE )
1139
- slots = install_new_memslots (kvm , as_id , slots );
1140
- kvfree (slots );
1141
1161
out_bitmap :
1142
1162
if (new .dirty_bitmap && !old .dirty_bitmap )
1143
1163
kvm_destroy_dirty_bitmap (& new );
0 commit comments