]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: Prevent internal slots from being COWed
authorAvi Kivity <avi@redhat.com>
Mon, 21 Jun 2010 07:57:45 +0000 (10:57 +0300)
committerAvi Kivity <avi@redhat.com>
Tue, 22 Jun 2010 11:17:15 +0000 (14:17 +0300)
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>
arch/x86/kvm/x86.c

index 1a6b87c90f2c791a94301b0d46d818127528b5cb..e18e68f62777d59c1c21e0350a5cbf6afdc217a5 100644 (file)
@@ -5491,6 +5491,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.
@@ -5503,7 +5508,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);