|
11 | 11 | * Christian Borntraeger <[email protected]>
|
12 | 12 | * Heiko Carstens <[email protected]>
|
13 | 13 | * Christian Ehrhardt <[email protected]>
|
| 14 | + * Jason J. Herne <[email protected]> |
14 | 15 | */
|
15 | 16 |
|
16 | 17 | #include <linux/compiler.h>
|
@@ -179,14 +180,62 @@ int kvm_dev_ioctl_check_extension(long ext)
|
179 | 180 | return r;
|
180 | 181 | }
|
181 | 182 |
|
| 183 | +static void kvm_s390_sync_dirty_log(struct kvm *kvm, |
| 184 | + struct kvm_memory_slot *memslot) |
| 185 | +{ |
| 186 | + gfn_t cur_gfn, last_gfn; |
| 187 | + unsigned long address; |
| 188 | + struct gmap *gmap = kvm->arch.gmap; |
| 189 | + |
| 190 | + down_read(&gmap->mm->mmap_sem); |
| 191 | + /* Loop over all guest pages */ |
| 192 | + last_gfn = memslot->base_gfn + memslot->npages; |
| 193 | + for (cur_gfn = memslot->base_gfn; cur_gfn <= last_gfn; cur_gfn++) { |
| 194 | + address = gfn_to_hva_memslot(memslot, cur_gfn); |
| 195 | + |
| 196 | + if (gmap_test_and_clear_dirty(address, gmap)) |
| 197 | + mark_page_dirty(kvm, cur_gfn); |
| 198 | + } |
| 199 | + up_read(&gmap->mm->mmap_sem); |
| 200 | +} |
| 201 | + |
182 | 202 | /* Section: vm related */
|
183 | 203 | /*
|
184 | 204 | * Get (and clear) the dirty memory log for a memory slot.
|
185 | 205 | */
|
186 | 206 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
|
187 | 207 | struct kvm_dirty_log *log)
|
188 | 208 | {
|
189 |
| - return 0; |
| 209 | + int r; |
| 210 | + unsigned long n; |
| 211 | + struct kvm_memory_slot *memslot; |
| 212 | + int is_dirty = 0; |
| 213 | + |
| 214 | + mutex_lock(&kvm->slots_lock); |
| 215 | + |
| 216 | + r = -EINVAL; |
| 217 | + if (log->slot >= KVM_USER_MEM_SLOTS) |
| 218 | + goto out; |
| 219 | + |
| 220 | + memslot = id_to_memslot(kvm->memslots, log->slot); |
| 221 | + r = -ENOENT; |
| 222 | + if (!memslot->dirty_bitmap) |
| 223 | + goto out; |
| 224 | + |
| 225 | + kvm_s390_sync_dirty_log(kvm, memslot); |
| 226 | + r = kvm_get_dirty_log(kvm, log, &is_dirty); |
| 227 | + if (r) |
| 228 | + goto out; |
| 229 | + |
| 230 | + /* Clear the dirty log */ |
| 231 | + if (is_dirty) { |
| 232 | + n = kvm_dirty_bitmap_bytes(memslot); |
| 233 | + memset(memslot->dirty_bitmap, 0, n); |
| 234 | + } |
| 235 | + r = 0; |
| 236 | +out: |
| 237 | + mutex_unlock(&kvm->slots_lock); |
| 238 | + return r; |
190 | 239 | }
|
191 | 240 |
|
192 | 241 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
|
|
0 commit comments