summaryrefslogtreecommitdiff
path: root/arch/powerpc/kvm/e500.c
diff options
context:
space:
mode:
authorHollis Blanchard <hollisb@us.ibm.com>2009-01-03 16:23:13 -0600
committerAvi Kivity <avi@redhat.com>2009-03-24 11:02:59 +0200
commitbb3a8a178dec1e46df3138a30f76acf67fe12397 (patch)
tree175effadbcdc3efb79e6b96a9f307052afaba46b /arch/powerpc/kvm/e500.c
parentbdc89f13ec955c14777d5caf02dfca3f51d639bd (diff)
KVM: ppc: Add extra E500 exceptions
e500 has additional interrupt vectors (and corresponding IVORs) for SPE and performance monitoring interrupts. Signed-off-by: Liu Yu <yu.liu@freescale.com> Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm/e500.c')
-rw-r--r--arch/powerpc/kvm/e500.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 7992da497cd4..d8067fd81cdd 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -21,6 +21,7 @@
#include <asm/kvm_e500.h>
#include <asm/kvm_ppc.h>
+#include "booke.h"
#include "e500_tlb.h"
void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
@@ -133,12 +134,29 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
static int kvmppc_e500_init(void)
{
- int r;
+ int r, i;
+ unsigned long ivor[3];
+ unsigned long max_ivor = 0;
r = kvmppc_booke_init();
if (r)
return r;
+ /* copy extra E500 exception handlers */
+ ivor[0] = mfspr(SPRN_IVOR32);
+ ivor[1] = mfspr(SPRN_IVOR33);
+ ivor[2] = mfspr(SPRN_IVOR34);
+ for (i = 0; i < 3; i++) {
+ if (ivor[i] > max_ivor)
+ max_ivor = ivor[i];
+
+ memcpy((void *)kvmppc_booke_handlers + ivor[i],
+ kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
+ kvmppc_handler_len);
+ }
+ flush_icache_range(kvmppc_booke_handlers,
+ kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+
return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
}