s390/mm: Add huge page dirty sync support
To do dirty loging with huge pages, we protect huge pmds in the gmap. When they are written to, we unprotect them and mark them dirty. We introduce the function gmap_test_and_clear_dirty_pmd which handles dirty sync for huge pages. Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Acked-by: David Hildenbrand <david@redhat.com>
此提交包含在:
@@ -511,19 +511,30 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
||||
}
|
||||
|
||||
static void kvm_s390_sync_dirty_log(struct kvm *kvm,
|
||||
struct kvm_memory_slot *memslot)
|
||||
struct kvm_memory_slot *memslot)
|
||||
{
|
||||
int i;
|
||||
gfn_t cur_gfn, last_gfn;
|
||||
unsigned long address;
|
||||
unsigned long gaddr, vmaddr;
|
||||
struct gmap *gmap = kvm->arch.gmap;
|
||||
DECLARE_BITMAP(bitmap, _PAGE_ENTRIES);
|
||||
|
||||
/* Loop over all guest pages */
|
||||
/* Loop over all guest segments */
|
||||
cur_gfn = memslot->base_gfn;
|
||||
last_gfn = memslot->base_gfn + memslot->npages;
|
||||
for (cur_gfn = memslot->base_gfn; cur_gfn <= last_gfn; cur_gfn++) {
|
||||
address = gfn_to_hva_memslot(memslot, cur_gfn);
|
||||
for (; cur_gfn <= last_gfn; cur_gfn += _PAGE_ENTRIES) {
|
||||
gaddr = gfn_to_gpa(cur_gfn);
|
||||
vmaddr = gfn_to_hva_memslot(memslot, cur_gfn);
|
||||
if (kvm_is_error_hva(vmaddr))
|
||||
continue;
|
||||
|
||||
bitmap_zero(bitmap, _PAGE_ENTRIES);
|
||||
gmap_sync_dirty_log_pmd(gmap, bitmap, gaddr, vmaddr);
|
||||
for (i = 0; i < _PAGE_ENTRIES; i++) {
|
||||
if (test_bit(i, bitmap))
|
||||
mark_page_dirty(kvm, cur_gfn + i);
|
||||
}
|
||||
|
||||
if (test_and_clear_guest_dirty(gmap->mm, address))
|
||||
mark_page_dirty(kvm, cur_gfn);
|
||||
if (fatal_signal_pending(current))
|
||||
return;
|
||||
cond_resched();
|
||||
|
新增問題並參考
封鎖使用者