Any chance we could merge struct kvm_vcpu_arch for both 44x and e500?

Signed-off-by: Liu Yu <[EMAIL PROTECTED]>
---
 arch/powerpc/include/asm/kvm_asm.h  |    7 ++-
 arch/powerpc/include/asm/kvm_host.h |  112 +++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/asm-offsets.c   |    9 +++
 arch/powerpc/kvm/44x_tlb.h          |    4 +
 arch/powerpc/kvm/Kconfig            |    4 +-
 arch/powerpc/kvm/Makefile           |    7 ++
 arch/powerpc/kvm/booke_guest.c      |   14 ++++-
 arch/powerpc/kvm/booke_host.c       |   20 ++++--
 arch/powerpc/kvm/emulate.c          |   88 +++++++++++++++++++++++++++-
 arch/powerpc/kvm/powerpc.c          |    4 +
 arch/powerpc/kvm/powerpc.h          |    4 +
 11 files changed, 261 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_asm.h 
b/arch/powerpc/include/asm/kvm_asm.h
index 2197764..7bf8b9a 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -42,7 +42,12 @@
 #define BOOKE_INTERRUPT_DTLB_MISS 13
 #define BOOKE_INTERRUPT_ITLB_MISS 14
 #define BOOKE_INTERRUPT_DEBUG 15
-#define BOOKE_MAX_INTERRUPT 15
+#define BOOKE_INTERRUPT_SPE_UNAVAIL 32
+#define BOOKE_INTERRUPT_SPE_FP_DATA 33
+#define BOOKE_INTERRUPT_SPE_FP_ROUND 34
+#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
+#define BOOKE_MAX_INTERRUPT 35
+#define BOOKE_INTERRUPT_NUM (BOOKE_MAX_INTERRUPT + 1)
 
 #define RESUME_FLAG_NV          (1<<0)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST        (1<<1)  /* Resume host? */
diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 34b52b7..d1b420b 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -64,6 +64,7 @@ struct kvm_vcpu_stat {
        u32 halt_wakeup;
 };
 
+#ifdef CONFIG_44x
 struct tlbe {
        u32 tid; /* Only the low 8 bits are used. */
        u32 word0;
@@ -155,6 +156,117 @@ struct kvm_vcpu_arch {
        struct timer_list dec_timer;
        unsigned long pending_exceptions;
 };
+#endif /* CONFIG_44x */
+
+#ifdef CONFIG_E500
+struct kvm_arch {
+};
+
+struct tlb_array{
+       void *base;
+       int size;
+};
+
+#define E500_PID_NUM   3
+#define E500_TLB_NUM   2
+
+struct kvm_vcpu_arch {
+       /* Unmodified copy of the guest's TLB. */
+       struct tlb_array guest_tlb[E500_TLB_NUM];
+       /* TLB that's actually used when the guest is running. */
+       struct tlb_array shadow_tlb[E500_TLB_NUM];
+       /* Pages which are referenced in the shadow TLB. */
+       struct page **shadow_pages[E500_TLB_NUM];
+
+       /* Track which TLB entries we've modified in the current exit. */
+       u8 *shadow_tlb_mod;
+
+       u32 host_stack;
+       u32 host_pid[E500_PID_NUM];
+       u32 host_dbcr0;
+       u32 host_dbcr1;
+       u32 host_dbcr2;
+       u32 host_iac[4];
+       u32 host_msr;
+
+       u64 fpr[32];
+       u32 gpr[32];
+
+       u32 pc;
+       u32 cr;
+       u32 ctr;
+       u32 lr;
+       u32 xer;
+
+       u32 msr;
+       u32 mmucr;
+       u32 sprg0;
+       u32 sprg1;
+       u32 sprg2;
+       u32 sprg3;
+       u32 sprg4;
+       u32 sprg5;
+       u32 sprg6;
+       u32 sprg7;
+       u32 srr0;
+       u32 srr1;
+       u32 csrr0;
+       u32 csrr1;
+       u32 dsrr0;
+       u32 dsrr1;
+       u32 dear;
+       u32 esr;
+       u32 dec;
+       u32 decar;
+       u32 tbl;
+       u32 tbu;
+       u32 tcr;
+       u32 tsr;
+       u32 ivor[BOOKE_INTERRUPT_NUM];
+       u32 ivpr;
+       u32 pir;
+
+       u32 shadow_pid;
+       u32 swap_pid;
+
+       u32 pid_array[0];
+       u32 pid;
+       u32 pid1;
+       u32 pid2;
+
+       u32 pvr;
+       u32 ccr0;
+       u32 ccr1;
+       u32 dbcr0;
+       u32 dbcr1;
+
+       u32 mas0;
+       u32 mas1;
+       u32 mas2;
+       u32 mas3;
+       u32 mas4;
+       u32 mas5;
+       u32 mas6;
+       u32 mas7;
+       u32 l1csr1;
+       u32 dbsr;
+
+       u32 last_inst;
+       u32 fault_dear;
+       u32 fault_esr;
+       gpa_t paddr_accessed;
+
+       u8 io_gpr; /* GPR used as IO source/target */
+       u8 mmio_is_bigendian;
+       u8 dcr_needed;
+       u8 dcr_is_write;
+
+       u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */
+
+       struct timer_list dec_timer;
+       unsigned long pending_exceptions;
+};
+#endif /* CONFIG_E500 */
 
 struct kvm_guest_debug {
        int enabled;
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 52649da..3385fb6 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -352,12 +352,15 @@ int main(void)
        DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE);
 
 #ifdef CONFIG_KVM
+# ifdef CONFIG_44x
        DEFINE(TLBE_BYTES, sizeof(struct tlbe));
+# endif
 
        DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
        DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
        DEFINE(VCPU_SHADOW_TLB, offsetof(struct kvm_vcpu, arch.shadow_tlb));
        DEFINE(VCPU_SHADOW_MOD, offsetof(struct kvm_vcpu, arch.shadow_tlb_mod));
+       DEFINE(SIZEOF_TLB_ARRAY, sizeof(struct tlb_array));
        DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
        DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
        DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
@@ -370,6 +373,12 @@ int main(void)
        DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
        DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7));
        DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid));
+       DEFINE(VCPU_PID, offsetof(struct kvm_vcpu, arch.pid));
+       DEFINE(VCPU_MAS0, offsetof(struct kvm_vcpu, arch.mas0));
+       DEFINE(VCPU_MAS1, offsetof(struct kvm_vcpu, arch.mas1));
+       DEFINE(VCPU_MAS2, offsetof(struct kvm_vcpu, arch.mas2));
+       DEFINE(VCPU_MAS3, offsetof(struct kvm_vcpu, arch.mas3));
+       DEFINE(VCPU_MAS7, offsetof(struct kvm_vcpu, arch.mas7));
 
        DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
        DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
diff --git a/arch/powerpc/kvm/44x_tlb.h b/arch/powerpc/kvm/44x_tlb.h
index 7eeffe7..673d7d5 100644
--- a/arch/powerpc/kvm/44x_tlb.h
+++ b/arch/powerpc/kvm/44x_tlb.h
@@ -23,6 +23,10 @@
 #include <linux/kvm_host.h>
 #include <asm/mmu-44x.h>
 
+#define kvmppc_emul_tlbre(vcpu, val)   EMULATE_DONE
+#define kvmppc_emul_tlbivax(vcpu, val) EMULATE_DONE
+#define kvmppc_tlb_init(vcpu)
+
 extern void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu);
 extern struct tlbe *kvmppc_tlb_search(struct kvm_vcpu *vcpu, gva_t eaddr,
                                 unsigned int pid, unsigned int as);
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 53aaa66..c812866 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -16,7 +16,7 @@ if VIRTUALIZATION
 
 config KVM
        bool "Kernel-based Virtual Machine (KVM) support"
-       depends on 44x && EXPERIMENTAL
+       depends on (44x || E500) && EXPERIMENTAL
        select PREEMPT_NOTIFIERS
        select ANON_INODES
        # We can only run on Book E hosts so far
@@ -32,7 +32,7 @@ config KVM
 
 config KVM_BOOKE_HOST
        bool "KVM host support for Book E PowerPC processors"
-       depends on KVM && 44x
+       depends on KVM && (44x || E500)
        ---help---
          Provides host support for KVM on Book E PowerPC processors. Currently
          this works on 440 processors only.
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 2a5d439..55a5bc3 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -13,5 +13,12 @@ obj-$(CONFIG_KVM) += kvm.o
 
 AFLAGS_booke_interrupts.o := -I$(obj)
 
+ifeq ($(CONFIG_44x),y)
 kvm-booke-host-objs := booke_host.o booke_interrupts.o 44x_tlb.o
+endif
+
+ifeq ($(CONFIG_E500),y)
+kvm-booke-host-objs := booke_host.o booke_fsl_interrupts.o e500_tlb.o
+endif
+
 obj-$(CONFIG_KVM_BOOKE_HOST) += kvm-booke-host.o
diff --git a/arch/powerpc/kvm/booke_guest.c b/arch/powerpc/kvm/booke_guest.c
index 4fca3be..830163a 100644
--- a/arch/powerpc/kvm/booke_guest.c
+++ b/arch/powerpc/kvm/booke_guest.c
@@ -53,7 +53,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { NULL }
 };
 
-static const u32 interrupt_msr_mask[16] = {
+static const u32 interrupt_msr_mask[] = {
        [BOOKE_INTERRUPT_CRITICAL]      = MSR_ME,
        [BOOKE_INTERRUPT_MACHINE_CHECK] = 0,
        [BOOKE_INTERRUPT_DATA_STORAGE]  = MSR_CE|MSR_ME|MSR_DE,
@@ -70,6 +70,9 @@ static const u32 interrupt_msr_mask[16] = {
        [BOOKE_INTERRUPT_DTLB_MISS]     = MSR_CE|MSR_ME|MSR_DE,
        [BOOKE_INTERRUPT_ITLB_MISS]     = MSR_CE|MSR_ME|MSR_DE,
        [BOOKE_INTERRUPT_DEBUG]         = MSR_ME,
+       [BOOKE_INTERRUPT_SPE_UNAVAIL]   = MSR_CE|MSR_ME|MSR_DE,
+       [BOOKE_INTERRUPT_SPE_FP_DATA]   = MSR_CE|MSR_ME|MSR_DE,
+       [BOOKE_INTERRUPT_SPE_FP_ROUND]  = MSR_CE|MSR_ME|MSR_DE
 };
 
 const unsigned char exception_priority[] = {
@@ -89,6 +92,9 @@ const unsigned char exception_priority[] = {
        [BOOKE_INTERRUPT_EXTERNAL] = 13,
        [BOOKE_INTERRUPT_FIT] = 14,
        [BOOKE_INTERRUPT_DECREMENTER] = 15,
+       [BOOKE_INTERRUPT_SPE_UNAVAIL] = 16,
+       [BOOKE_INTERRUPT_SPE_FP_DATA] = 17,
+       [BOOKE_INTERRUPT_SPE_FP_ROUND] = 18
 };
 
 const unsigned char priority_exception[] = {
@@ -108,6 +114,9 @@ const unsigned char priority_exception[] = {
        BOOKE_INTERRUPT_EXTERNAL,
        BOOKE_INTERRUPT_FIT,
        BOOKE_INTERRUPT_DECREMENTER,
+       BOOKE_INTERRUPT_SPE_UNAVAIL,
+       BOOKE_INTERRUPT_SPE_FP_DATA,
+       BOOKE_INTERRUPT_SPE_FP_ROUND
 };
 
 /* TODO: use vcpu_printf() */
@@ -280,6 +289,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu 
*vcpu,
                break;
 
        case BOOKE_INTERRUPT_FP_UNAVAIL:
+       case BOOKE_INTERRUPT_SPE_UNAVAIL:
+       case BOOKE_INTERRUPT_SPE_FP_DATA:
+       case BOOKE_INTERRUPT_SPE_FP_ROUND:
                kvmppc_queue_exception(vcpu, exit_nr);
                r = RESUME_GUEST;
                break;
diff --git a/arch/powerpc/kvm/booke_host.c b/arch/powerpc/kvm/booke_host.c
index b480341..c8edb98 100644
--- a/arch/powerpc/kvm/booke_host.c
+++ b/arch/powerpc/kvm/booke_host.c
@@ -27,9 +27,9 @@ unsigned long kvmppc_booke_handlers;
 
 static int kvmppc_booke_init(void)
 {
-       unsigned long ivor[16];
+       unsigned long ivor[BOOKE_INTERRUPT_NUM];
        unsigned long max_ivor = 0;
-       int i;
+       int i, valid_ivor;
 
        /* We install our own exception handlers by hijacking IVPR. IVPR must
         * be 16-bit aligned, so we need a 64KB allocation. */
@@ -42,6 +42,7 @@ static int kvmppc_booke_init(void)
 
        /* Copy our interrupt handlers to match host IVORs. That way we don't
         * have to swap the IVORs on every guest/host transition. */
+       memset(ivor, 0, sizeof(ivor));
        ivor[0] = mfspr(SPRN_IVOR0);
        ivor[1] = mfspr(SPRN_IVOR1);
        ivor[2] = mfspr(SPRN_IVOR2);
@@ -58,14 +59,21 @@ static int kvmppc_booke_init(void)
        ivor[13] = mfspr(SPRN_IVOR13);
        ivor[14] = mfspr(SPRN_IVOR14);
        ivor[15] = mfspr(SPRN_IVOR15);
+       ivor[32] = mfspr(SPRN_IVOR32);
+       ivor[33] = mfspr(SPRN_IVOR33);
+       ivor[34] = mfspr(SPRN_IVOR34);
 
-       for (i = 0; i < 16; i++) {
+       for (i = 0, valid_ivor = 0; i < BOOKE_INTERRUPT_NUM; i++) {
                if (ivor[i] > max_ivor)
                        max_ivor = ivor[i];
 
-               memcpy((void *)kvmppc_booke_handlers + ivor[i],
-                      kvmppc_handlers_start + i * kvmppc_handler_len,
-                      kvmppc_handler_len);
+               if (ivor[i]) {
+                       memcpy((void *)kvmppc_booke_handlers + ivor[i],
+                               kvmppc_handlers_start +
+                               valid_ivor * kvmppc_handler_len,
+                               kvmppc_handler_len);
+                       valid_ivor++;
+               }
        }
        flush_icache_range(kvmppc_booke_handlers,
                           kvmppc_booke_handlers + max_ivor + 
kvmppc_handler_len);
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 5d31fca..2243c1a 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -232,6 +232,10 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
                                vcpu->arch.gpr[rt] = vcpu->arch.mmucr; break;
                        case SPRN_PID:
                                vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
+                       case SPRN_PID1:
+                               vcpu->arch.gpr[rt] = vcpu->arch.pid1; break;
+                       case SPRN_PID2:
+                               vcpu->arch.gpr[rt] = vcpu->arch.pid2; break;
                        case SPRN_IVPR:
                                vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
                        case SPRN_CCR0:
@@ -248,6 +252,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
                                vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
                        case SPRN_DBCR1:
                                vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
+                       case SPRN_DBSR:
+                               vcpu->arch.gpr[rt] = vcpu->arch.dbsr; break;
 
                        /* Note: mftb and TBRL/TBWL are user-accessible, so
                         * the guest can always access the real TB anyways.
@@ -300,6 +306,45 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
                                vcpu->arch.gpr[rt] = vcpu->arch.ivor[14]; break;
                        case SPRN_IVOR15:
                                vcpu->arch.gpr[rt] = vcpu->arch.ivor[15]; break;
+                       case SPRN_IVOR32:
+                               vcpu->arch.gpr[rt] = vcpu->arch.ivor[32]; break;
+                       case SPRN_IVOR33:
+                               vcpu->arch.gpr[rt] = vcpu->arch.ivor[33]; break;
+                       case SPRN_IVOR34:
+                               vcpu->arch.gpr[rt] = vcpu->arch.ivor[34]; break;
+                       case SPRN_IVOR35:
+                               vcpu->arch.gpr[rt] = vcpu->arch.ivor[35]; break;
+#ifdef CONFIG_E500
+                       /* E500 MMU */
+                       case SPRN_MAS0:
+                               vcpu->arch.gpr[rt] = vcpu->arch.mas0; break;
+                       case SPRN_MAS1:
+                               vcpu->arch.gpr[rt] = vcpu->arch.mas1; break;
+                       case SPRN_MAS2:
+                               vcpu->arch.gpr[rt] = vcpu->arch.mas2; break;
+                       case SPRN_MAS3:
+                               vcpu->arch.gpr[rt] = vcpu->arch.mas3; break;
+                       case SPRN_MAS4:
+                               vcpu->arch.gpr[rt] = vcpu->arch.mas4; break;
+                       case SPRN_MAS6:
+                               vcpu->arch.gpr[rt] = vcpu->arch.mas6; break;
+                       case SPRN_MAS7:
+                               vcpu->arch.gpr[rt] = vcpu->arch.mas7; break;
+                       case SPRN_TLB0CFG:
+                               vcpu->arch.gpr[rt] = mfspr(SPRN_TLB0CFG);
+                               vcpu->arch.gpr[rt] &= ~0xfffUL;
+                               vcpu->arch.gpr[rt] |= 
vcpu->arch.guest_tlb[1].size;
+                               break;
+
+                       case SPRN_TLB1CFG:
+                               vcpu->arch.gpr[rt] = mfspr(SPRN_TLB1CFG);
+                               vcpu->arch.gpr[rt] &= ~0xfffUL;
+                               vcpu->arch.gpr[rt] |= 
vcpu->arch.guest_tlb[1].size;
+                               break;
+
+                       case SPRN_L1CSR1:
+                               vcpu->arch.gpr[rt] = vcpu->arch.l1csr1; break;
+#endif /* CONFIG_E500 */
 
                        default:
                                printk("mfspr: unknown spr %x\n", sprn);
@@ -310,8 +355,6 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
 
                case 407:                                       /* sthx */
                        rs = get_rs(inst);
-                       ra = get_ra(inst);
-                       rb = get_rb(inst);
 
                        emulated = kvmppc_handle_store(run, vcpu,
                                                       vcpu->arch.gpr[rs],
@@ -364,6 +407,10 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
                                vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
                        case SPRN_PID:
                                kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break;
+                       case SPRN_PID1:
+                               vcpu->arch.pid1 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_PID2:
+                               vcpu->arch.pid2 = vcpu->arch.gpr[rs]; break;
                        case SPRN_CCR0:
                                vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
                        case SPRN_CCR1:
@@ -376,6 +423,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
                                vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
                        case SPRN_DBCR1:
                                vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_DBSR:
+                               vcpu->arch.dbsr = vcpu->arch.gpr[rs]; break;
 
                        /* XXX We need to context-switch the timebase for
                         * watchdog and FIT. */
@@ -450,6 +499,33 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
                                vcpu->arch.ivor[14] = vcpu->arch.gpr[rs]; break;
                        case SPRN_IVOR15:
                                vcpu->arch.ivor[15] = vcpu->arch.gpr[rs]; break;
+                       case SPRN_IVOR32:
+                               vcpu->arch.ivor[32] = vcpu->arch.gpr[rs]; break;
+                       case SPRN_IVOR33:
+                               vcpu->arch.ivor[33] = vcpu->arch.gpr[rs]; break;
+                       case SPRN_IVOR34:
+                               vcpu->arch.ivor[34] = vcpu->arch.gpr[rs]; break;
+                       case SPRN_IVOR35:
+                               vcpu->arch.ivor[35] = vcpu->arch.gpr[rs]; break;
+#ifdef CONFIG_E500
+                       /* E500 MMU */
+                       case SPRN_MAS0:
+                               vcpu->arch.mas0 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_MAS1:
+                               vcpu->arch.mas1 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_MAS2:
+                               vcpu->arch.mas2 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_MAS3:
+                               vcpu->arch.mas3 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_MAS4:
+                               vcpu->arch.mas4 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_MAS6:
+                               vcpu->arch.mas6 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_MAS7:
+                               vcpu->arch.mas7 = vcpu->arch.gpr[rs]; break;
+                       case SPRN_L1CSR1:
+                               vcpu->arch.l1csr1 = vcpu->arch.gpr[rs]; break;
+#endif /* CONFIG_E500 */
 
                        default:
                                printk("mtspr: unknown spr %x\n", sprn);
@@ -484,6 +560,10 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
                                                       4, 0);
                        break;
 
+               case 786:                                       /* tlbivax */
+                       emulated = kvmppc_emul_tlbivax(vcpu, inst);
+                       break;
+
                case 978:                                       /* tlbwe */
                        emulated = kvmppc_emul_tlbwe(vcpu, inst);
                        break;
@@ -492,6 +572,10 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
                        emulated = kvmppc_emul_tlbsx(vcpu, inst);
                        break;
 
+               case 946:                                       /* tlbre */
+                       emulated = kvmppc_emul_tlbre(vcpu, inst);
+                       break;
+
                case 790:                                       /* lhbrx */
                        rt = get_rt(inst);
                        emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index d3bc29f..493ac93 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -29,6 +29,7 @@
 #include <asm/kvm_ppc.h>
 #include <asm/tlbflush.h>
 
+#include "powerpc.h"
 
 gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
@@ -102,6 +103,8 @@ void kvm_arch_check_processor_compat(void *rtn)
 
        if (strcmp(cur_cpu_spec->platform, "ppc440") == 0)
                r = 0;
+       else if (strcmp(cur_cpu_spec->cpu_name, "e500v2") == 0)
+               r = 0;
        else
                r = -ENOTSUPP;
 
@@ -230,6 +233,7 @@ static void kvmppc_decrementer_func(unsigned long data)
 
 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 {
+       kvmppc_tlb_init(vcpu);
        setup_timer(&vcpu->arch.dec_timer, kvmppc_decrementer_func,
                    (unsigned long)vcpu);
 
diff --git a/arch/powerpc/kvm/powerpc.h b/arch/powerpc/kvm/powerpc.h
index dd93461..3a7ac82 100644
--- a/arch/powerpc/kvm/powerpc.h
+++ b/arch/powerpc/kvm/powerpc.h
@@ -7,4 +7,8 @@
 #include "44x_tlb.h"
 #endif
 
+#ifdef CONFIG_E500
+#include "e500_tlb.h"
+#endif
+
 #endif /* __KVM_POWERPC_POWERPC_H__ */
-- 
1.5.4

--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to