]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.36.2/kvm-write-protect-memory-after-slot-swap.patch
Fixes for 5.10
[thirdparty/kernel/stable-queue.git] / releases / 2.6.36.2 / kvm-write-protect-memory-after-slot-swap.patch
CommitLineData
d86d85d9
GKH
1From edde99ce05290e50ce0b3495d209e54e6349ab47 Mon Sep 17 00:00:00 2001
2From: Michael S. Tsirkin <mst@redhat.com>
3Date: Mon, 25 Oct 2010 03:21:24 +0200
4Subject: KVM: Write protect memory after slot swap
5
6From: Michael S. Tsirkin <mst@redhat.com>
7
8commit edde99ce05290e50ce0b3495d209e54e6349ab47 upstream.
9
10I have observed the following bug trigger:
11
121. userspace calls GET_DIRTY_LOG
132. kvm_mmu_slot_remove_write_access is called and makes a page ro
143. page fault happens and makes the page writeable
15 fault is logged in the bitmap appropriately
164. kvm_vm_ioctl_get_dirty_log swaps slot pointers
17
18a lot of time passes
19
205. guest writes into the page
216. userspace calls GET_DIRTY_LOG
22
23At point (5), bitmap is clean and page is writeable,
24thus, guest modification of memory is not logged
25and GET_DIRTY_LOG returns an empty bitmap.
26
27The rule is that all pages are either dirty in the current bitmap,
28or write-protected, which is violated here.
29
30It seems that just moving kvm_mmu_slot_remove_write_access down
31to after the slot pointer swap should fix this bug.
32
33Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
34Signed-off-by: Avi Kivity <avi@redhat.com>
35Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
36
37---
38 arch/x86/kvm/x86.c | 8 ++++----
39 1 file changed, 4 insertions(+), 4 deletions(-)
40
41--- a/arch/x86/kvm/x86.c
42+++ b/arch/x86/kvm/x86.c
43@@ -2912,10 +2912,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
44 struct kvm_memslots *slots, *old_slots;
45 unsigned long *dirty_bitmap;
46
47- spin_lock(&kvm->mmu_lock);
48- kvm_mmu_slot_remove_write_access(kvm, log->slot);
49- spin_unlock(&kvm->mmu_lock);
50-
51 r = -ENOMEM;
52 dirty_bitmap = vmalloc(n);
53 if (!dirty_bitmap)
54@@ -2937,6 +2933,10 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
55 dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
56 kfree(old_slots);
57
58+ spin_lock(&kvm->mmu_lock);
59+ kvm_mmu_slot_remove_write_access(kvm, log->slot);
60+ spin_unlock(&kvm->mmu_lock);
61+
62 r = -EFAULT;
63 if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) {
64 vfree(dirty_bitmap);