diff options
author | Hollis Blanchard <hollisb@us.ibm.com> | 2009-01-03 17:23:13 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-24 05:02:59 -0400 |
commit | bb3a8a178dec1e46df3138a30f76acf67fe12397 (patch) | |
tree | 175effadbcdc3efb79e6b96a9f307052afaba46b /arch/powerpc/kvm/e500.c | |
parent | bdc89f13ec955c14777d5caf02dfca3f51d639bd (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.c | 20 |
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 @@ | |||
21 | #include <asm/kvm_e500.h> | 21 | #include <asm/kvm_e500.h> |
22 | #include <asm/kvm_ppc.h> | 22 | #include <asm/kvm_ppc.h> |
23 | 23 | ||
24 | #include "booke.h" | ||
24 | #include "e500_tlb.h" | 25 | #include "e500_tlb.h" |
25 | 26 | ||
26 | void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu) | 27 | void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu) |
@@ -133,12 +134,29 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) | |||
133 | 134 | ||
134 | static int kvmppc_e500_init(void) | 135 | static int kvmppc_e500_init(void) |
135 | { | 136 | { |
136 | int r; | 137 | int r, i; |
138 | unsigned long ivor[3]; | ||
139 | unsigned long max_ivor = 0; | ||
137 | 140 | ||
138 | r = kvmppc_booke_init(); | 141 | r = kvmppc_booke_init(); |
139 | if (r) | 142 | if (r) |
140 | return r; | 143 | return r; |
141 | 144 | ||
145 | /* copy extra E500 exception handlers */ | ||
146 | ivor[0] = mfspr(SPRN_IVOR32); | ||
147 | ivor[1] = mfspr(SPRN_IVOR33); | ||
148 | ivor[2] = mfspr(SPRN_IVOR34); | ||
149 | for (i = 0; i < 3; i++) { | ||
150 | if (ivor[i] > max_ivor) | ||
151 | max_ivor = ivor[i]; | ||
152 | |||
153 | memcpy((void *)kvmppc_booke_handlers + ivor[i], | ||
154 | kvmppc_handlers_start + (i + 16) * kvmppc_handler_len, | ||
155 | kvmppc_handler_len); | ||
156 | } | ||
157 | flush_icache_range(kvmppc_booke_handlers, | ||
158 | kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); | ||
159 | |||
142 | return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE); | 160 | return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE); |
143 | } | 161 | } |
144 | 162 | ||