summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-06-21 10:57:45 +0300
committerAvi Kivity <avi@redhat.com>2010-08-01 10:47:08 +0300
commit7ac77099ce88a0c31b75acd0ec5ef3da4415a6d8 (patch)
tree20fcf29491d762cb0d378c6bbda0aadb81748418
parente36d96f7cfaa71870c407131eb4fbd38ea285c01 (diff)
downloadop-kernel-dev-7ac77099ce88a0c31b75acd0ec5ef3da4415a6d8.zip
op-kernel-dev-7ac77099ce88a0c31b75acd0ec5ef3da4415a6d8.tar.gz
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>
-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 7ef4410..68be38e 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,
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);
OpenPOWER on IntegriCloud