mirror of
https://github.com/qemu/qemu.git
synced 2024-11-25 11:53:39 +08:00
Make KVM slot management more robust
KVM keeps track of physical memory based on slots in the kernel. The current code that translates QEMU memory mappings to slots work but is not robust in the fact of reregistering partial regions of memory. This patch does the right thing for reregistering partial regions of memory. It also prevents QEMU from using KVM private slots. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5734 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
87006d1378
commit
62d60e8cc4
44
kvm-all.c
44
kvm-all.c
@ -50,6 +50,9 @@ static KVMSlot *kvm_alloc_slot(KVMState *s)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
|
||||
/* KVM private memory slots */
|
||||
if (i >= 8 && i < 12)
|
||||
continue;
|
||||
if (s->slots[i].memory_size == 0)
|
||||
return &s->slots[i];
|
||||
}
|
||||
@ -327,10 +330,45 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr,
|
||||
|
||||
kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, mem);
|
||||
} else if (start_addr >= mem->guest_phys_addr &&
|
||||
(start_addr + size) <= (mem->guest_phys_addr + mem->memory_size))
|
||||
return;
|
||||
}
|
||||
(start_addr + size) <= (mem->guest_phys_addr +
|
||||
mem->memory_size)) {
|
||||
KVMSlot slot;
|
||||
target_phys_addr_t mem_start;
|
||||
ram_addr_t mem_size, mem_offset;
|
||||
|
||||
/* Not splitting */
|
||||
if ((phys_offset - (start_addr - mem->guest_phys_addr)) ==
|
||||
((uint8_t *)mem->userspace_addr - phys_ram_base))
|
||||
return;
|
||||
|
||||
/* unregister whole slot */
|
||||
memcpy(&slot, mem, sizeof(slot));
|
||||
mem->memory_size = 0;
|
||||
kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, mem);
|
||||
|
||||
/* register prefix slot */
|
||||
mem_start = slot.guest_phys_addr;
|
||||
mem_size = start_addr - slot.guest_phys_addr;
|
||||
mem_offset = (uint8_t *)slot.userspace_addr - phys_ram_base;
|
||||
if (mem_size)
|
||||
kvm_set_phys_mem(mem_start, mem_size, mem_offset);
|
||||
|
||||
/* register new slot */
|
||||
kvm_set_phys_mem(start_addr, size, phys_offset);
|
||||
|
||||
/* register suffix slot */
|
||||
mem_start = start_addr + size;
|
||||
mem_offset += mem_size + size;
|
||||
mem_size = slot.memory_size - mem_size - size;
|
||||
if (mem_size)
|
||||
kvm_set_phys_mem(mem_start, mem_size, mem_offset);
|
||||
|
||||
return;
|
||||
} else {
|
||||
printf("Registering overlapping slot\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
/* KVM does not need to know about this memory */
|
||||
if (flags >= IO_MEM_UNASSIGNED)
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user