*/
#include <linux/kvm_host.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <asm/reg.h>
#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)
kvmppc_e500_tlb_setup(vcpu_e500);
- /* Use the same core vertion as host's */
+ /* Registers init */
vcpu->arch.pvr = mfspr(SPRN_PVR);
+ /* Since booke kvm only support one core, update all vcpus' PIR to 0 */
+ vcpu->vcpu_id = 0;
+
return 0;
}
kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
}
-static int kvmppc_e500_init(void)
+static int __init 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);
}
-static void kvmppc_e500_exit(void)
+static void __init kvmppc_e500_exit(void)
{
kvmppc_booke_exit();
}