aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-06-21 03:57:45 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:47:08 -0400
commit7ac77099ce88a0c31b75acd0ec5ef3da4415a6d8 (patch)
tree20fcf29491d762cb0d378c6bbda0aadb81748418 /arch/x86/kvm/x86.c
parente36d96f7cfaa71870c407131eb4fbd38ea285c01 (diff)
KVM: Prevent internal slots from being COWed
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>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7ef44107a14a..68be38e233f5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5491,6 +5491,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
5491 int user_alloc) 5491 int user_alloc)
5492{ 5492{
5493 int npages = memslot->npages; 5493 int npages = memslot->npages;
5494 int map_flags = MAP_PRIVATE | MAP_ANONYMOUS;
5495
5496 /* Prevent internal slot pages from being moved by fork()/COW. */
5497 if (memslot->id >= KVM_MEMORY_SLOTS)
5498 map_flags = MAP_SHARED | MAP_ANONYMOUS;
5494 5499
5495 /*To keep backward compatibility with older userspace, 5500 /*To keep backward compatibility with older userspace,
5496 *x86 needs to hanlde !user_alloc case. 5501 *x86 needs to hanlde !user_alloc case.
@@ -5503,7 +5508,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
5503 userspace_addr = do_mmap(NULL, 0, 5508 userspace_addr = do_mmap(NULL, 0,
5504 npages * PAGE_SIZE, 5509 npages * PAGE_SIZE,
5505 PROT_READ | PROT_WRITE, 5510 PROT_READ | PROT_WRITE,
5506 MAP_PRIVATE | MAP_ANONYMOUS, 5511 map_flags,
5507 0); 5512 0);
5508 up_write(&current->mm->mmap_sem); 5513 up_write(&current->mm->mmap_sem);
5509 5514