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