]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
KVM: Prevent internal slots from being COWed
authorAvi Kivity <avi@redhat.com>
Fri, 17 Sep 2010 16:13:14 +0000 (13:13 -0300)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 27 Sep 2010 00:18:33 +0000 (17:18 -0700)
commit 7ac77099ce88a0c31b75acd0ec5ef3da4415a6d8 upstream.

If a process with a memory slot is COWed, the page will change its address
(despite having an elevated reference count).  This breaks internal memory
slots which have their physical addresses loaded into vmcs registers (see
the APIC access memory slot).

Signed-off-by: Avi Kivity <avi@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/x86/kvm/x86.c

index 7fa89c39c64f67df0a62804cfa242ae6a2d6f638..fd2268838ca2e1be29406373489ee25e65b5da33 100644 (file)
@@ -5438,6 +5438,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
                                int user_alloc)
 {
        int npages = memslot->npages;
+       int map_flags = MAP_PRIVATE | MAP_ANONYMOUS;
+
+       /* Prevent internal slot pages from being moved by fork()/COW. */
+       if (memslot->id >= KVM_MEMORY_SLOTS)
+               map_flags = MAP_SHARED | MAP_ANONYMOUS;
 
        /*To keep backward compatibility with older userspace,
         *x86 needs to hanlde !user_alloc case.
@@ -5450,7 +5455,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
                        userspace_addr = do_mmap(NULL, 0,
                                                 npages * PAGE_SIZE,
                                                 PROT_READ | PROT_WRITE,
-                                                MAP_PRIVATE | MAP_ANONYMOUS,
+                                                map_flags,
                                                 0);
                        up_write(&current->mm->mmap_sem);