===================================================================
@@ -1076,20 +1076,6 @@ int kvm_deassign_pci_device(kvm_context_
}
#endif
-int kvm_destroy_memory_region_works(kvm_context_t kvm)
-{
- int ret = 0;
-
-#ifdef KVM_CAP_DESTROY_MEMORY_REGION_WORKS
- ret =
- kvm_ioctl(kvm_state, KVM_CHECK_EXTENSION,
- KVM_CAP_DESTROY_MEMORY_REGION_WORKS);
- if (ret <= 0)
- ret = 0;
-#endif
- return ret;
-}
-
int kvm_reinject_control(kvm_context_t kvm, int pit_reinject)
{
#ifdef KVM_CAP_REINJECT_CONTROL
@@ -2055,11 +2041,6 @@ int kvm_main_loop(void)
return 0;
}
-#ifdef TARGET_I386
-static int destroy_region_works = 0;
-#endif
-
-
#if !defined(TARGET_I386)
int kvm_arch_init_irq_routing(void)
{
@@ -2071,6 +2052,10 @@ extern int no_hpet;
static int kvm_create_context(void)
{
+ static const char upgrade_note[] =
+ "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
+ "(see http://sourceforge.net/projects/kvm).\n";
+
int r;
if (!kvm_irqchip) {
@@ -2094,9 +2079,16 @@ static int kvm_create_context(void)
return -1;
}
}
-#ifdef TARGET_I386
- destroy_region_works = kvm_destroy_memory_region_works(kvm_context);
-#endif
+
+ /* There was a nasty bug in < kvm-80 that prevents memory slots from being
+ * destroyed properly. Since we rely on this capability, refuse to work
+ * with any kernel without this capability. */
+ if (!kvm_check_extension(kvm_state, KVM_CAP_DESTROY_MEMORY_REGION_WORKS)) {
+ fprintf(stderr,
+ "KVM kernel module broken (DESTROY_MEMORY_REGION).\n%s",
+ upgrade_note);
+ return -EINVAL;
+ }
r = kvm_arch_init_irq_routing();
if (r < 0) {
@@ -2134,73 +2126,11 @@ static int kvm_create_context(void)
return 0;
}
-#ifdef TARGET_I386
-static int must_use_aliases_source(target_phys_addr_t addr)
-{
- if (destroy_region_works)
- return false;
- if (addr == 0xa0000 || addr == 0xa8000)
- return true;
- return false;
-}
-
-static int must_use_aliases_target(target_phys_addr_t addr)
-{
- if (destroy_region_works)
- return false;
- if (addr >= 0xe0000000 && addr < 0x100000000ull)
- return true;
- return false;
-}
-
-static struct mapping {
- target_phys_addr_t phys;
- ram_addr_t ram;
- ram_addr_t len;
-} mappings[50];
-static int nr_mappings;
-
-static struct mapping *find_ram_mapping(ram_addr_t ram_addr)
-{
- struct mapping *p;
-
- for (p = mappings; p < mappings + nr_mappings; ++p) {
- if (p->ram <= ram_addr && ram_addr < p->ram + p->len) {
- return p;
- }
- }
- return NULL;
-}
-
-static struct mapping *find_mapping(target_phys_addr_t start_addr)
-{
- struct mapping *p;
-
- for (p = mappings; p < mappings + nr_mappings; ++p) {
- if (p->phys <= start_addr && start_addr < p->phys + p->len) {
- return p;
- }
- }
- return NULL;
-}
-
-static void drop_mapping(target_phys_addr_t start_addr)
-{
- struct mapping *p = find_mapping(start_addr);
-
- if (p)
- *p = mappings[--nr_mappings];
-}
-#endif
-
void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
ram_addr_t phys_offset)
{
int r = 0;
unsigned long area_flags;
-#ifdef TARGET_I386
- struct mapping *p;
-#endif
if (start_addr + size > phys_ram_size) {
phys_ram_size = start_addr + size;
@@ -2210,19 +2140,13 @@ void kvm_set_phys_mem(target_phys_addr_t
area_flags = phys_offset & ~TARGET_PAGE_MASK;
if (area_flags != IO_MEM_RAM) {
-#ifdef TARGET_I386
- if (must_use_aliases_source(start_addr)) {
- kvm_destroy_memory_alias(kvm_context, start_addr);
- return;
- }
- if (must_use_aliases_target(start_addr))
- return;
-#endif
while (size > 0) {
- p = find_mapping(start_addr);
- if (p) {
- kvm_unregister_memory_area(kvm_context, p->phys, p->len);
- drop_mapping(p->phys);
+ int slot;
+
+ slot = get_slot(start_addr);
+ if (slot != -1) {
+ kvm_unregister_memory_area(kvm_context, slots[slot].phys_addr,
+ slots[slot].len);
}
start_addr += TARGET_PAGE_SIZE;
if (size > TARGET_PAGE_SIZE) {
@@ -2241,30 +2165,12 @@ void kvm_set_phys_mem(target_phys_addr_t
if (area_flags >= TLB_MMIO)
return;
-#ifdef TARGET_I386
- if (must_use_aliases_source(start_addr)) {
- p = find_ram_mapping(phys_offset);
- if (p) {
- kvm_create_memory_alias(kvm_context, start_addr, size,
- p->phys + (phys_offset - p->ram));
- }
- return;
- }
-#endif
-
r = kvm_register_phys_mem(kvm_context, start_addr,
qemu_get_ram_ptr(phys_offset), size, 0);
if (r < 0) {
printf("kvm_cpu_register_physical_memory: failed\n");
exit(1);
}
-#ifdef TARGET_I386
- drop_mapping(start_addr);
- p = &mappings[nr_mappings++];
- p->phys = start_addr;
- p->ram = phys_offset;
- p->len = size;
-#endif
return;
}
@@ -2342,10 +2248,6 @@ void kvm_qemu_log_memory(target_phys_add
if (log)
kvm_dirty_pages_log_enable_slot(kvm_context, start, size);
else {
-#ifdef TARGET_I386
- if (must_use_aliases_target(start))
- return;
-#endif
kvm_dirty_pages_log_disable_slot(kvm_context, start, size);
}
}
@@ -2418,12 +2320,6 @@ int kvm_physical_sync_dirty_bitmap(targe
target_phys_addr_t end_addr)
{
#ifndef TARGET_IA64
-
-#ifdef TARGET_I386
- if (must_use_aliases_source(start_addr))
- return 0;
-#endif
-
kvm_get_dirty_pages_range(kvm_context, start_addr,
end_addr - start_addr, NULL,
kvm_get_dirty_bitmap_cb);
@@ -2433,11 +2329,6 @@ int kvm_physical_sync_dirty_bitmap(targe
int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t len)
{
-#ifdef TARGET_I386
- if (must_use_aliases_source(phys_addr))
- return 0;
-#endif
-
#ifndef TARGET_IA64
kvm_qemu_log_memory(phys_addr, len, 1);
#endif
@@ -2446,11 +2337,6 @@ int kvm_log_start(target_phys_addr_t phy
int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t len)
{
-#ifdef TARGET_I386
- if (must_use_aliases_source(phys_addr))
- return 0;
-#endif
-
#ifndef TARGET_IA64
kvm_qemu_log_memory(phys_addr, len, 0);
#endif
===================================================================
@@ -214,71 +214,6 @@ int kvm_arch_run(CPUState *env)
return r;
}
-#define MAX_ALIAS_SLOTS 4
-static struct {
- uint64_t start;
- uint64_t len;
-} kvm_aliases[MAX_ALIAS_SLOTS];
-
-static int get_alias_slot(uint64_t start)
-{
- int i;
-
- for (i=0; i<MAX_ALIAS_SLOTS; i++)
- if (kvm_aliases[i].start == start)
- return i;
- return -1;
-}
-static int get_free_alias_slot(void)
-{
- int i;
-
- for (i=0; i<MAX_ALIAS_SLOTS; i++)
- if (kvm_aliases[i].len == 0)
- return i;
- return -1;
-}
-
-static void register_alias(int slot, uint64_t start, uint64_t len)
-{
- kvm_aliases[slot].start = start;
- kvm_aliases[slot].len = len;
-}
-
-int kvm_create_memory_alias(kvm_context_t kvm,
- uint64_t phys_start,
- uint64_t len,
- uint64_t target_phys)
-{
- struct kvm_memory_alias alias = {
- .flags = 0,
- .guest_phys_addr = phys_start,
- .memory_size = len,
- .target_phys_addr = target_phys,
- };
- int r;
- int slot;
-
- slot = get_alias_slot(phys_start);
- if (slot < 0)
- slot = get_free_alias_slot();
- if (slot < 0)
- return -EBUSY;
- alias.slot = slot;
-
- r = kvm_vm_ioctl(kvm_state, KVM_SET_MEMORY_ALIAS, &alias);
- if (r == -1)
- return -errno;
-
- register_alias(slot, phys_start, len);
- return 0;
-}
-
-int kvm_destroy_memory_alias(kvm_context_t kvm, uint64_t phys_start)
-{
- return kvm_create_memory_alias(kvm, phys_start, 0, 0);
-}
-
#ifdef KVM_CAP_IRQCHIP
int kvm_get_lapic(CPUState *env, struct kvm_lapic_state *s)
@@ -616,18 +551,6 @@ static int kvm_enable_tpr_access_reporti
}
#endif
-int kvm_qemu_create_memory_alias(uint64_t phys_start,
- uint64_t len,
- uint64_t target_phys)
-{
- return kvm_create_memory_alias(kvm_context, phys_start, len, target_phys);
-}
-
-int kvm_qemu_destroy_memory_alias(uint64_t phys_start)
-{
- return kvm_destroy_memory_alias(kvm_context, phys_start);
-}
-
#ifdef KVM_CAP_ADJUST_CLOCK
static struct kvm_clock_data kvmclock_data;
===================================================================
@@ -400,23 +400,6 @@ int kvm_unregister_coalesced_mmio(kvm_co
uint32_t size);
/*!
- * \brief Create a memory alias
- *
- * Aliases a portion of physical memory to another portion. If the guest
- * accesses the alias region, it will behave exactly as if it accessed
- * the target memory.
- */
-int kvm_create_memory_alias(kvm_context_t, uint64_t phys_start, uint64_t len,
- uint64_t target_phys);
-
-/*!
- * \brief Destroy a memory alias
- *
- * Removes an alias created with kvm_create_memory_alias().
- */
-int kvm_destroy_memory_alias(kvm_context_t, uint64_t phys_start);
-
-/*!
* \brief Get a bitmap of guest ram pages which are allocated to the guest.
*
* \param kvm Pointer to the current kvm_context
@@ -651,15 +634,6 @@ int kvm_deassign_irq(kvm_context_t kvm,
#endif
#endif
-/*!
- * \brief Determines whether destroying memory regions is allowed
- *
- * KVM before 2.6.29 had a bug when destroying memory regions.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_destroy_memory_region_works(kvm_context_t kvm);
-
#ifdef KVM_CAP_DEVICE_DEASSIGNMENT
/*!
* \brief Notifies host kernel about a PCI device to be deassigned from a guest