@@ -846,6 +846,100 @@ struct kvm_memory_slot *id_to_memslot(struct kvm_memslots *slots, int id)
846846 return NULL ;
847847}
848848
849+ /* Iterator used for walking memslots that overlap a gfn range. */
850+ struct kvm_memslot_iter {
851+ struct kvm_memslots *slots;
852+ struct rb_node *node;
853+ struct kvm_memory_slot *slot;
854+ };
855+
856+ static inline void kvm_memslot_iter_next (struct kvm_memslot_iter *iter)
857+ {
858+ iter->node = rb_next (iter->node );
859+ if (!iter->node )
860+ return ;
861+
862+ iter->slot = container_of (iter->node , struct kvm_memory_slot , gfn_node[iter->slots ->node_idx ]);
863+ }
864+
865+ static inline void kvm_memslot_iter_start (struct kvm_memslot_iter *iter,
866+ struct kvm_memslots *slots,
867+ gfn_t start)
868+ {
869+ int idx = slots->node_idx ;
870+ struct rb_node *tmp;
871+ struct kvm_memory_slot *slot;
872+
873+ iter->slots = slots;
874+
875+ /*
876+ * Find the so called "upper bound" of a key - the first node that has
877+ * its key strictly greater than the searched one (the start gfn in our case).
878+ */
879+ iter->node = NULL ;
880+ for (tmp = slots->gfn_tree .rb_node ; tmp; ) {
881+ slot = container_of (tmp, struct kvm_memory_slot , gfn_node[idx]);
882+ if (start < slot->base_gfn ) {
883+ iter->node = tmp;
884+ tmp = tmp->rb_left ;
885+ } else {
886+ tmp = tmp->rb_right ;
887+ }
888+ }
889+
890+ /*
891+ * Find the slot with the lowest gfn that can possibly intersect with
892+ * the range, so we'll ideally have slot start <= range start
893+ */
894+ if (iter->node ) {
895+ /*
896+ * A NULL previous node means that the very first slot
897+ * already has a higher start gfn.
898+ * In this case slot start > range start.
899+ */
900+ tmp = rb_prev (iter->node );
901+ if (tmp)
902+ iter->node = tmp;
903+ } else {
904+ /* a NULL node below means no slots */
905+ iter->node = rb_last (&slots->gfn_tree );
906+ }
907+
908+ if (iter->node ) {
909+ iter->slot = container_of (iter->node , struct kvm_memory_slot , gfn_node[idx]);
910+
911+ /*
912+ * It is possible in the slot start < range start case that the
913+ * found slot ends before or at range start (slot end <= range start)
914+ * and so it does not overlap the requested range.
915+ *
916+ * In such non-overlapping case the next slot (if it exists) will
917+ * already have slot start > range start, otherwise the logic above
918+ * would have found it instead of the current slot.
919+ */
920+ if (iter->slot ->base_gfn + iter->slot ->npages <= start)
921+ kvm_memslot_iter_next (iter);
922+ }
923+ }
924+
925+ static inline bool kvm_memslot_iter_is_valid (struct kvm_memslot_iter *iter, gfn_t end)
926+ {
927+ if (!iter->node )
928+ return false ;
929+
930+ /*
931+ * If this slot starts beyond or at the end of the range so does
932+ * every next one
933+ */
934+ return iter->slot ->base_gfn < end;
935+ }
936+
937+ /* Iterate over each memslot at least partially intersecting [start, end) range */
938+ #define kvm_for_each_memslot_in_gfn_range (iter, slots, start, end ) \
939+ for (kvm_memslot_iter_start(iter, slots, start); \
940+ kvm_memslot_iter_is_valid (iter, end); \
941+ kvm_memslot_iter_next (iter))
942+
849943/*
850944 * KVM_SET_USER_MEMORY_REGION ioctl allows the following operations:
851945 * - create a new memory slot
0 commit comments