aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2014-09-11 12:22:57 +0200
committerAlexander Graf <agraf@suse.de>2014-11-04 23:26:11 +0100
commit9ac58dc59aaf9db20ec17df9b372915bee9b0f02 (patch)
treee642ad02fba2fa58dadb9e76881273dc9927f4e2
parent4aee73623d0141c5d4ce4754fc054689fb92f0e5 (diff)
PPC: openpic_kvm: Only map first occurence in address space
The in-kernel OpenPIC emulation only supports a single map. However, we map the OpenPIC at 2 locations: The CPU visible one and the PCI visible one. For KVM acceleration, we only care about the first one. To make sure that we only map that first mapping and not the PCI map that happens dynamically later during bootup, ignore maps that happen when we are already considering ourselves mapped. Credits due are to Bogdan and Mihai for debugging this. Reported-by: Bogdan Purcareata <bogdan.purcareata@freescale.com> Reported-by: Mihai Caraman <mihai.caraman@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--hw/intc/openpic_kvm.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c
index e3bce043a3..3e2cd189ff 100644
--- a/hw/intc/openpic_kvm.c
+++ b/hw/intc/openpic_kvm.c
@@ -45,6 +45,7 @@ typedef struct KVMOpenPICState {
MemoryListener mem_listener;
uint32_t fd;
uint32_t model;
+ hwaddr mapped;
} KVMOpenPICState;
static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level)
@@ -128,7 +129,16 @@ static void kvm_openpic_region_add(MemoryListener *listener,
return;
}
+ if (opp->mapped) {
+ /*
+ * We can only map the MPIC once. Since we are already mapped,
+ * the best we can do is ignore new maps.
+ */
+ return;
+ }
+
reg_base = section->offset_within_address_space;
+ opp->mapped = reg_base;
attr.group = KVM_DEV_MPIC_GRP_MISC;
attr.attr = KVM_DEV_MPIC_BASE_ADDR;
@@ -155,6 +165,15 @@ static void kvm_openpic_region_del(MemoryListener *listener,
return;
}
+ if (section->offset_within_address_space != opp->mapped) {
+ /*
+ * We can only map the MPIC once. This mapping was a secondary
+ * one that we couldn't fulfill. Ignore it.
+ */
+ return;
+ }
+ opp->mapped = 0;
+
attr.group = KVM_DEV_MPIC_GRP_MISC;
attr.attr = KVM_DEV_MPIC_BASE_ADDR;
attr.addr = (uint64_t)(unsigned long)&reg_base;