[PATCH 01/10] Add dbsr in kvm_vcpu_arch

2008-12-18 Thread Liu Yu
Kernel for E500 need clear dbsr when startup.
So add dbsr register in kvm_vcpu_arch for BOOKE.

Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/include/asm/kvm_host.h |1 +
 arch/powerpc/kvm/booke_emulate.c|4 
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 850c41e..63962fa 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -163,6 +163,7 @@ struct kvm_vcpu_arch {
u32 ccr1;
u32 dbcr0;
u32 dbcr1;
+   u32 dbsr;
 
 #ifdef CONFIG_KVM_EXIT_TIMING
struct kvmppc_exit_timing timing_exit;
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index 2fe9429..aaa304f 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -111,6 +111,8 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int 
sprn, int rs)
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;
case SPRN_TSR:
vcpu-arch.tsr = ~vcpu-arch.gpr[rs]; break;
case SPRN_TCR:
@@ -204,6 +206,8 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int 
sprn, int rt)
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;
 
case SPRN_IVOR0:
vcpu-arch.gpr[rt] = vcpu-arch.ivor[BOOKE_IRQPRIO_CRITICAL];
-- 
1.5.4

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


[PATCH 03/10] Put iccci into 44x specific code

2008-12-18 Thread Liu Yu
E500 deosn't support this instruction.

Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/kvm/booke_interrupts.S |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/booke_interrupts.S 
b/arch/powerpc/kvm/booke_interrupts.S
index 084ebcd..4679ec2 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -347,7 +347,9 @@ lightweight_exit:
lwz r3, VCPU_SHADOW_PID(r4)
mtspr   SPRN_PID, r3
 
+#ifdef CONFIG_44x
iccci   0, 0 /* XXX hack */
+#endif
 
/* Load some guest volatiles. */
lwz r0, VCPU_GPR(r0)(r4)
-- 
1.5.4

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


[PATCH 04/10] E500 core-specific code

2008-12-18 Thread Liu Yu
Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/include/asm/kvm_e500.h |   67 +++
 arch/powerpc/kvm/e500.c |  151 +++
 2 files changed, 218 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/include/asm/kvm_e500.h
 create mode 100644 arch/powerpc/kvm/e500.c

diff --git a/arch/powerpc/include/asm/kvm_e500.h 
b/arch/powerpc/include/asm/kvm_e500.h
new file mode 100644
index 000..9d497ce
--- /dev/null
+++ b/arch/powerpc/include/asm/kvm_e500.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, yu@freescale.com
+ *
+ * Description:
+ * This file is derived from arch/powerpc/include/asm/kvm_44x.h,
+ * by Hollis Blanchard holl...@us.ibm.com.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_KVM_E500_H__
+#define __ASM_KVM_E500_H__
+
+#include linux/kvm_host.h
+
+#define BOOKE_INTERRUPT_SIZE 36
+
+#define E500_PID_NUM   3
+#define E500_TLB_NUM   2
+
+struct tlbe{
+   u32 mas1;
+   u32 mas2;
+   u32 mas3;
+   u32 mas7;
+};
+
+struct kvmppc_vcpu_e500 {
+   /* Unmodified copy of the guest's TLB. */
+   struct tlbe *guest_tlb[E500_TLB_NUM];
+   /* TLB that's actually used when the guest is running. */
+   struct tlbe *shadow_tlb[E500_TLB_NUM];
+   /* Pages which are referenced in the shadow TLB. */
+   struct page **shadow_pages[E500_TLB_NUM];
+
+   unsigned int guest_tlb_size[E500_TLB_NUM];
+   unsigned int shadow_tlb_size[E500_TLB_NUM];
+   unsigned int guest_tlb_nv[E500_TLB_NUM];
+
+   u32 host_pid[E500_PID_NUM];
+   u32 pid[E500_PID_NUM];
+
+   u32 mas0;
+   u32 mas1;
+   u32 mas2;
+   u32 mas3;
+   u32 mas4;
+   u32 mas5;
+   u32 mas6;
+   u32 mas7;
+   u32 l1csr1;
+   u32 hid0;
+   u32 hid1;
+
+   struct kvm_vcpu vcpu;
+};
+
+static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu)
+{
+   return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu);
+}
+
+#endif /* __ASM_KVM_E500_H__ */
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
new file mode 100644
index 000..7992da4
--- /dev/null
+++ b/arch/powerpc/kvm/e500.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, yu@freescale.com
+ *
+ * Description:
+ * This file is derived from arch/powerpc/kvm/44x.c,
+ * by Hollis Blanchard holl...@us.ibm.com.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include linux/kvm_host.h
+#include linux/err.h
+
+#include asm/reg.h
+#include asm/cputable.h
+#include asm/tlbflush.h
+#include asm/kvm_e500.h
+#include asm/kvm_ppc.h
+
+#include e500_tlb.h
+
+void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+{
+   kvmppc_e500_tlb_load(vcpu, cpu);
+}
+
+void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
+{
+   kvmppc_e500_tlb_put(vcpu);
+}
+
+int kvmppc_core_check_processor_compat(void)
+{
+   int r;
+
+   if (strcmp(cur_cpu_spec-cpu_name, e500v2) == 0)
+   r = 0;
+   else
+   r = -ENOTSUPP;
+
+   return r;
+}
+
+int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
+{
+   struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+   kvmppc_e500_tlb_setup(vcpu_e500);
+
+   /* Use the same core vertion as host's */
+   vcpu-arch.pvr = mfspr(SPRN_PVR);
+
+   return 0;
+}
+
+/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
+int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
+   struct kvm_translation *tr)
+{
+   int index;
+   gva_t eaddr;
+   u8 pid;
+   u8 as;
+
+   eaddr = tr-linear_address;
+   pid = (tr-linear_address  32)  0xff;
+   as = (tr-linear_address  40)  0x1;
+
+   index = kvmppc_e500_tlb_search(vcpu, eaddr, pid, as);
+   if (index  0) {
+   tr-valid = 0;
+   return 0;
+   }
+
+   tr-physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
+   /* XXX what does writeable and usermode even mean? */
+   tr-valid = 1;
+
+   return 0;
+}
+
+struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
+{
+   struct kvmppc_vcpu_e500 *vcpu_e500;
+   struct kvm_vcpu *vcpu;
+   int err;
+
+   vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
+   if (!vcpu_e500) {
+   err = -ENOMEM;
+   goto out;
+   }
+
+   vcpu = vcpu_e500-vcpu;
+   err = 

[PATCH 06/10] E500 TLB emulation

2008-12-18 Thread Liu Yu
Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/kvm/e500_tlb.c |  737 +++
 arch/powerpc/kvm/e500_tlb.h |  184 +++
 2 files changed, 921 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/kvm/e500_tlb.c
 create mode 100644 arch/powerpc/kvm/e500_tlb.h

diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
new file mode 100644
index 000..6a50340
--- /dev/null
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -0,0 +1,737 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, yu@freescale.com
+ *
+ * Description:
+ * This file is based on arch/powerpc/kvm/44x_tlb.c,
+ * by Hollis Blanchard holl...@us.ibm.com.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include linux/types.h
+#include linux/string.h
+#include linux/kvm.h
+#include linux/kvm_host.h
+#include linux/highmem.h
+#include asm/kvm_ppc.h
+#include asm/kvm_e500.h
+
+#include e500_tlb.h
+
+#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
+
+static unsigned int tlb1_entry_num;
+
+void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
+{
+   struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+   struct tlbe *tlbe;
+   int i, tlbsel;
+
+   printk(| %8s | %8s | %8s | %8s | %8s |\n,
+   nr, mas1, mas2, mas3, mas7);
+
+   for (tlbsel = 0; tlbsel  2; tlbsel++) {
+   printk(Guest TLB%d:\n, tlbsel);
+   for (i = 0; i  vcpu_e500-guest_tlb_size[tlbsel]; i++) {
+   tlbe = vcpu_e500-guest_tlb[tlbsel][i];
+   if (tlbe-mas1  MAS1_VALID)
+   printk( G[%d][%3d] |  %08X | %08X | %08X | 
%08X |\n,
+   tlbsel, i, tlbe-mas1, tlbe-mas2,
+   tlbe-mas3, tlbe-mas7);
+   }
+   }
+
+   for (tlbsel = 0; tlbsel  2; tlbsel++) {
+   printk(Shadow TLB%d:\n, tlbsel);
+   for (i = 0; i  vcpu_e500-shadow_tlb_size[tlbsel]; i++) {
+   tlbe = vcpu_e500-shadow_tlb[tlbsel][i];
+   if (tlbe-mas1  MAS1_VALID)
+   printk( S[%d][%3d] |  %08X | %08X | %08X | 
%08X |\n,
+   tlbsel, i, tlbe-mas1, tlbe-mas2,
+   tlbe-mas3, tlbe-mas7);
+   }
+   }
+}
+
+static inline unsigned int tlb0_get_next_victim(
+   struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+   unsigned int victim;
+
+   victim = vcpu_e500-guest_tlb_nv[0]++;
+   if (unlikely(vcpu_e500-guest_tlb_nv[0] = KVM_E500_TLB0_WAY_NUM))
+   vcpu_e500-guest_tlb_nv[0] = 0;
+
+   return victim;
+}
+
+static inline unsigned int tlb1_max_shadow_size(void)
+{
+   return tlb1_entry_num - tlbcam_index;
+}
+
+static inline int tlbe_is_writable(struct tlbe *tlbe)
+{
+   return tlbe-mas3  (MAS3_SW|MAS3_UW);
+}
+
+static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
+{
+   /* Mask off reserved bits. */
+   mas3 = MAS3_ATTRIB_MASK;
+
+   if (!usermode) {
+   /* Guest is in supervisor mode,
+* so we need to translate guest
+* supervisor permissions into user permissions. */
+   mas3 = ~E500_TLB_USER_PERM_MASK;
+   mas3 |= (mas3  E500_TLB_SUPER_PERM_MASK)  1;
+   }
+
+   return mas3 | E500_TLB_SUPER_PERM_MASK;
+}
+
+static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode)
+{
+   return mas2  MAS2_ATTRIB_MASK;
+}
+
+/*
+ * writing shadow tlb entry to host TLB
+ */
+static inline void __write_host_tlbe(struct tlbe *stlbe)
+{
+   mtspr(SPRN_MAS1, stlbe-mas1);
+   mtspr(SPRN_MAS2, stlbe-mas2);
+   mtspr(SPRN_MAS3, stlbe-mas3);
+   mtspr(SPRN_MAS7, stlbe-mas7);
+   __asm__ __volatile__ (tlbwe\n : : );
+}
+
+static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
+   int tlbsel, int esel)
+{
+   struct tlbe *stlbe = vcpu_e500-shadow_tlb[tlbsel][esel];
+
+   local_irq_disable();
+   if (tlbsel == 0) {
+   __write_host_tlbe(stlbe);
+   } else {
+   unsigned register mas0;
+
+   mas0 = mfspr(SPRN_MAS0);
+
+   mtspr(SPRN_MAS0, MAS0_TLBSEL(1) | 
MAS0_ESEL(to_htlb1_esel(esel)));
+   __write_host_tlbe(stlbe);
+
+   mtspr(SPRN_MAS0, mas0);
+   }
+   local_irq_enable();
+}
+
+void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu)
+{
+   struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+   int i;
+   unsigned register mas0;
+
+   /* Load all valid TLB1 entries to reduce guest tlb miss fault */
+   local_irq_disable();
+   mas0 = mfspr(SPRN_MAS0);
+   for (i = 0; i  

[PATCH 09/10] Fix IRQ priority search confusion

2008-12-18 Thread Liu Yu
Although BOOKE_MAX_INTERRUPT has the right value, the meaning is not match.

Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/kvm/booke.c |2 +-
 arch/powerpc/kvm/booke.h |1 +
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 933c406..f192fbe 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -163,7 +163,7 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
unsigned int priority;
 
priority = __ffs(*pending);
-   while (priority = BOOKE_MAX_INTERRUPT) {
+   while (priority = BOOKE_IRQPRIO_MAX) {
if (kvmppc_booke_irqprio_deliver(vcpu, priority))
break;
 
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index 311fdbc..7ceeb3e 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -42,6 +42,7 @@
 #define BOOKE_IRQPRIO_EXTERNAL 13
 #define BOOKE_IRQPRIO_FIT 14
 #define BOOKE_IRQPRIO_DECREMENTER 15
+#define BOOKE_IRQPRIO_MAX 15
 
 /* Helper function for full MSR writes. No need to call this if only EE is
  * changing. */
-- 
1.5.4

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


[PATCH 10/10] Add extra E500 exceptions

2008-12-18 Thread Liu Yu
Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/include/asm/kvm_asm.h  |7 ++-
 arch/powerpc/include/asm/kvm_host.h |2 +-
 arch/powerpc/kvm/booke.c|   18 ++
 arch/powerpc/kvm/booke.h|   30 ++
 arch/powerpc/kvm/booke_interrupts.S |3 +++
 arch/powerpc/kvm/e500.c |   20 +++-
 arch/powerpc/kvm/e500_emulate.c |   27 +++
 7 files changed, 92 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_asm.h 
b/arch/powerpc/include/asm/kvm_asm.h
index 2197764..56bfae5 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
+
+/* E500 */
+#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 RESUME_FLAG_NV  (10)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST(11)  /* Resume host? */
diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 63962fa..5e22681 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -150,7 +150,7 @@ struct kvm_vcpu_arch {
u32 tbu;
u32 tcr;
u32 tsr;
-   u32 ivor[16];
+   u32 ivor[64];
ulong ivpr;
u32 pir;
 
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index f192fbe..642e420 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -118,6 +118,9 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu 
*vcpu,
case BOOKE_IRQPRIO_DATA_STORAGE:
case BOOKE_IRQPRIO_INST_STORAGE:
case BOOKE_IRQPRIO_FP_UNAVAIL:
+   case BOOKE_IRQPRIO_SPE_UNAVAIL:
+   case BOOKE_IRQPRIO_SPE_FP_DATA:
+   case BOOKE_IRQPRIO_SPE_FP_ROUND:
case BOOKE_IRQPRIO_AP_UNAVAIL:
case BOOKE_IRQPRIO_ALIGNMENT:
allowed = 1;
@@ -261,6 +264,21 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
r = RESUME_GUEST;
break;
 
+   case BOOKE_INTERRUPT_SPE_UNAVAIL:
+   kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_UNAVAIL);
+   r = RESUME_GUEST;
+   break;
+
+   case BOOKE_INTERRUPT_SPE_FP_DATA:
+   kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_DATA);
+   r = RESUME_GUEST;
+   break;
+
+   case BOOKE_INTERRUPT_SPE_FP_ROUND:
+   kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND);
+   r = RESUME_GUEST;
+   break;
+
case BOOKE_INTERRUPT_DATA_STORAGE:
vcpu-arch.dear = vcpu-arch.fault_dear;
vcpu-arch.esr = vcpu-arch.fault_esr;
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index 7ceeb3e..d59bcca 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -31,18 +31,24 @@
 #define BOOKE_IRQPRIO_ALIGNMENT 2
 #define BOOKE_IRQPRIO_PROGRAM 3
 #define BOOKE_IRQPRIO_FP_UNAVAIL 4
-#define BOOKE_IRQPRIO_SYSCALL 5
-#define BOOKE_IRQPRIO_AP_UNAVAIL 6
-#define BOOKE_IRQPRIO_DTLB_MISS 7
-#define BOOKE_IRQPRIO_ITLB_MISS 8
-#define BOOKE_IRQPRIO_MACHINE_CHECK 9
-#define BOOKE_IRQPRIO_DEBUG 10
-#define BOOKE_IRQPRIO_CRITICAL 11
-#define BOOKE_IRQPRIO_WATCHDOG 12
-#define BOOKE_IRQPRIO_EXTERNAL 13
-#define BOOKE_IRQPRIO_FIT 14
-#define BOOKE_IRQPRIO_DECREMENTER 15
-#define BOOKE_IRQPRIO_MAX 15
+#define BOOKE_IRQPRIO_SPE_UNAVAIL 5
+#define BOOKE_IRQPRIO_SPE_FP_DATA 6
+#define BOOKE_IRQPRIO_SPE_FP_ROUND 7
+#define BOOKE_IRQPRIO_SYSCALL 8
+#define BOOKE_IRQPRIO_AP_UNAVAIL 9
+#define BOOKE_IRQPRIO_DTLB_MISS 10
+#define BOOKE_IRQPRIO_ITLB_MISS 11
+#define BOOKE_IRQPRIO_MACHINE_CHECK 12
+#define BOOKE_IRQPRIO_DEBUG 13
+#define BOOKE_IRQPRIO_CRITICAL 14
+#define BOOKE_IRQPRIO_WATCHDOG 15
+#define BOOKE_IRQPRIO_EXTERNAL 16
+#define BOOKE_IRQPRIO_FIT 17
+#define BOOKE_IRQPRIO_DECREMENTER 18
+#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19
+#define BOOKE_IRQPRIO_MAX 19
+
+extern unsigned long kvmppc_booke_handlers;
 
 /* Helper function for full MSR writes. No need to call this if only EE is
  * changing. */
diff --git a/arch/powerpc/kvm/booke_interrupts.S 
b/arch/powerpc/kvm/booke_interrupts.S
index 4679ec2..d0c6f84 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -86,6 +86,9 @@ KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG
 KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS
 KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS
 KVM_HANDLER BOOKE_INTERRUPT_DEBUG
+KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL
+KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
+KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND
 
 _GLOBAL(kvmppc_handler_len)
.long kvmppc_handler_1 - kvmppc_handler_0
diff 

[PATCH 08/10] Enable E500 in KVM

2008-12-18 Thread Liu Yu
Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/kvm/Kconfig  |   13 +
 arch/powerpc/kvm/Makefile |9 +
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 6dbdc48..1465705 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -43,6 +43,19 @@ config KVM_EXIT_TIMING
 
  If unsure, say N.
 
+config KVM_E500
+   bool KVM support for PowerPC E500 processors
+   depends on EXPERIMENTAL  E500
+   select KVM
+   ---help---
+ Support running unmodified E500 guest kernels in virtual machines on
+ E500 host processors.
+
+ This module provides access to the hardware capabilities through
+ a character device node named /dev/kvm.
+
+ If unsure, say N.
+
 config KVM_TRACE
bool KVM trace support
depends on KVM  MARKERS  SYSFS
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 3ef5261..4b2df66 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -22,3 +22,12 @@ kvm-440-objs := \
44x_tlb.o \
44x_emulate.o
 obj-$(CONFIG_KVM_440) += kvm-440.o
+
+kvm-e500-objs := \
+   booke.o \
+   booke_emulate.o \
+   booke_interrupts.o \
+   e500.o \
+   e500_tlb.o \
+   e500_emulate.o
+obj-$(CONFIG_KVM_E500) += kvm-e500.o
-- 
1.5.4

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


Re: [PATCH 07/10] Add kvmppc_mmu_dtlb/itlb_miss for booke

2008-12-18 Thread Hollis Blanchard
On Thu, 2008-12-18 at 20:22 +0800, Liu Yu wrote:
 When itlb or dtlb miss happens, E500 needs to update some mmu registers.
 So that the auto-load mechanism can work on E500 when write a tlb entry.
 
 Signed-off-by: Liu Yu yu@freescale.com
 ---
  arch/powerpc/include/asm/kvm_ppc.h |2 ++
  arch/powerpc/kvm/44x_tlb.c |8 
  arch/powerpc/kvm/booke.c   |2 ++
  3 files changed, 12 insertions(+), 0 deletions(-)
 
 diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
 b/arch/powerpc/include/asm/kvm_ppc.h
 index f4b041b..82547c8 100644
 --- a/arch/powerpc/include/asm/kvm_ppc.h
 +++ b/arch/powerpc/include/asm/kvm_ppc.h
 @@ -63,6 +63,8 @@ extern int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, 
 gva_t eaddr);
  extern int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
  extern gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index,
gva_t eaddr);
 +extern void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu);
 +extern void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu);
 
  extern struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm,
  unsigned int id);
 diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
 index e67b731..4a16f47 100644
 --- a/arch/powerpc/kvm/44x_tlb.c
 +++ b/arch/powerpc/kvm/44x_tlb.c
 @@ -232,6 +232,14 @@ int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t 
 eaddr)
   return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu-arch.pid, as);
  }
 
 +void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu)
 +{
 +}
 +
 +void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu)
 +{
 +}
 +
  static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x,
unsigned int stlb_index)
  {
 diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
 index a73b395..933c406 100644
 --- a/arch/powerpc/kvm/booke.c
 +++ b/arch/powerpc/kvm/booke.c
 @@ -295,6 +295,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
 kvm_vcpu *vcpu,
   kvmppc_booke_queue_irqprio(vcpu, 
 BOOKE_IRQPRIO_DTLB_MISS);
   vcpu-arch.dear = vcpu-arch.fault_dear;
   vcpu-arch.esr = vcpu-arch.fault_esr;
 + kvmppc_mmu_dtlb_miss(vcpu);
   kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS);
   r = RESUME_GUEST;
   break;
 @@ -337,6 +338,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
 kvm_vcpu *vcpu,
   if (gtlb_index  0) {
   /* The guest didn't have a mapping for it. */
   kvmppc_booke_queue_irqprio(vcpu, 
 BOOKE_IRQPRIO_ITLB_MISS);
 + kvmppc_mmu_itlb_miss(vcpu);
   kvmppc_account_exit(vcpu, ITLB_REAL_MISS_EXITS);
   break;
   }

I don't think you've supplied an implementation of these hooks for e500.
Does it build with this patch series applied?

-- 
Hollis Blanchard
IBM Linux Technology Center

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


RE: [PATCH 07/10] Add kvmppc_mmu_dtlb/itlb_miss for booke

2008-12-18 Thread Liu Yu

 -Original Message-
 From: kvm-ppc-ow...@vger.kernel.org 
 [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Hollis Blanchard
 Sent: Friday, December 19, 2008 7:49 AM
 To: Liu Yu-B13201
 Cc: kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 07/10] Add kvmppc_mmu_dtlb/itlb_miss for booke
 
 On Thu, 2008-12-18 at 20:22 +0800, Liu Yu wrote:
  When itlb or dtlb miss happens, E500 needs to update some 
 mmu registers.
  So that the auto-load mechanism can work on E500 when write 
 a tlb entry.
  
  Signed-off-by: Liu Yu yu@freescale.com
  ---
   arch/powerpc/include/asm/kvm_ppc.h |2 ++
   arch/powerpc/kvm/44x_tlb.c |8 
   arch/powerpc/kvm/booke.c   |2 ++
   3 files changed, 12 insertions(+), 0 deletions(-)
  
  diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
 b/arch/powerpc/include/asm/kvm_ppc.h
  index f4b041b..82547c8 100644
  --- a/arch/powerpc/include/asm/kvm_ppc.h
  +++ b/arch/powerpc/include/asm/kvm_ppc.h
  @@ -63,6 +63,8 @@ extern int kvmppc_mmu_dtlb_index(struct 
 kvm_vcpu *vcpu, gva_t eaddr);
   extern int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, 
 gva_t eaddr);
   extern gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, 
 unsigned int gtlb_index,
 gva_t eaddr);
  +extern void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu);
  +extern void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu);
  
   extern struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm,
   unsigned int id);
  diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
  index e67b731..4a16f47 100644
  --- a/arch/powerpc/kvm/44x_tlb.c
  +++ b/arch/powerpc/kvm/44x_tlb.c
  @@ -232,6 +232,14 @@ int kvmppc_mmu_dtlb_index(struct 
 kvm_vcpu *vcpu, gva_t eaddr)
  return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu-arch.pid, as);
   }
  
  +void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu)
  +{
  +}
  +
  +void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu)
  +{
  +}
  +
   static void kvmppc_44x_shadow_release(struct 
 kvmppc_vcpu_44x *vcpu_44x,
 unsigned int stlb_index)
   {
  diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
  index a73b395..933c406 100644
  --- a/arch/powerpc/kvm/booke.c
  +++ b/arch/powerpc/kvm/booke.c
  @@ -295,6 +295,7 @@ int kvmppc_handle_exit(struct kvm_run 
 *run, struct kvm_vcpu *vcpu,
  kvmppc_booke_queue_irqprio(vcpu, 
 BOOKE_IRQPRIO_DTLB_MISS);
  vcpu-arch.dear = vcpu-arch.fault_dear;
  vcpu-arch.esr = vcpu-arch.fault_esr;
  +   kvmppc_mmu_dtlb_miss(vcpu);
  kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS);
  r = RESUME_GUEST;
  break;
  @@ -337,6 +338,7 @@ int kvmppc_handle_exit(struct kvm_run 
 *run, struct kvm_vcpu *vcpu,
  if (gtlb_index  0) {
  /* The guest didn't have a mapping for it. */
  kvmppc_booke_queue_irqprio(vcpu, 
 BOOKE_IRQPRIO_ITLB_MISS);
  +   kvmppc_mmu_itlb_miss(vcpu);
  kvmppc_account_exit(vcpu, ITLB_REAL_MISS_EXITS);
  break;
  }
 
 I don't think you've supplied an implementation of these 
 hooks for e500.
 Does it build with this patch series applied?
 

Sorry, these hooks for e500 exists in [PATCH 06/10] E500 TLB
emulation.

--
+static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
+   unsigned int eaddr, int as)
+{
+   struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+   unsigned int victim, pidsel, tsized;
+   int tlbsel;
+
+   /* since we only have two TLBs, only lower bit is used. */
+   tlbsel = (vcpu_e500-mas4  28)  0x1;
+   victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0;
+   pidsel = (vcpu_e500-mas4  16)  0xf;
+   tsized = (vcpu_e500-mas4  8)  0xf;
+
+   vcpu_e500-mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
+   | MAS0_NV(vcpu_e500-guest_tlb_nv[tlbsel]);
+   vcpu_e500-mas1 = MAS1_VALID | (as ? MAS1_TS : 0)
+   | MAS1_TID(vcpu_e500-pid[pidsel])
+   | MAS1_TSIZE(tsized);
+   vcpu_e500-mas2 = (eaddr  MAS2_EPN)
+   | (vcpu_e500-mas4  MAS2_ATTRIB_MASK);
+   vcpu_e500-mas3 = MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3;
+   vcpu_e500-mas6 = (vcpu_e500-mas6  MAS6_SPID1)
+   | (get_cur_pid(vcpu)  16)
+   | (as ? MAS6_SAS : 0);
+   vcpu_e500-mas7 = 0;
+}

+void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu)
+{
+   unsigned int as = !!(vcpu-arch.msr  MSR_IS);
+
+   kvmppc_e500_deliver_tlb_miss(vcpu, vcpu-arch.pc, as);
+}
+
+void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu)
+{
+   unsigned int as = !!(vcpu-arch.msr  MSR_DS);
+
+   kvmppc_e500_deliver_tlb_miss(vcpu, vcpu-arch.fault_dear, as);
+}
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message 

[PATCH 06/10 v3] E500 TLB emulation

2008-12-18 Thread Liu Yu
Signed-off-by: Liu Yu yu@freescale.com
---
[v2]
1. rename a lot functions in e500_tlb.c in order to get a clearer hierarchy.
2. remove unmatched comments.
3. adjust mask to make sure tlbsel always be safe.

[v3]
fix wrong spelling in comments.

 arch/powerpc/kvm/e500_tlb.c |  737 +++
 arch/powerpc/kvm/e500_tlb.h |  184 +++
 2 files changed, 921 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/kvm/e500_tlb.c
 create mode 100644 arch/powerpc/kvm/e500_tlb.h

diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
new file mode 100644
index 000..30ce5c7
--- /dev/null
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -0,0 +1,737 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, yu@freescale.com
+ *
+ * Description:
+ * This file is based on arch/powerpc/kvm/44x_tlb.c,
+ * by Hollis Blanchard holl...@us.ibm.com.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include linux/types.h
+#include linux/string.h
+#include linux/kvm.h
+#include linux/kvm_host.h
+#include linux/highmem.h
+#include asm/kvm_ppc.h
+#include asm/kvm_e500.h
+
+#include e500_tlb.h
+
+#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
+
+static unsigned int tlb1_entry_num;
+
+void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
+{
+   struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+   struct tlbe *tlbe;
+   int i, tlbsel;
+
+   printk(| %8s | %8s | %8s | %8s | %8s |\n,
+   nr, mas1, mas2, mas3, mas7);
+
+   for (tlbsel = 0; tlbsel  2; tlbsel++) {
+   printk(Guest TLB%d:\n, tlbsel);
+   for (i = 0; i  vcpu_e500-guest_tlb_size[tlbsel]; i++) {
+   tlbe = vcpu_e500-guest_tlb[tlbsel][i];
+   if (tlbe-mas1  MAS1_VALID)
+   printk( G[%d][%3d] |  %08X | %08X | %08X | 
%08X |\n,
+   tlbsel, i, tlbe-mas1, tlbe-mas2,
+   tlbe-mas3, tlbe-mas7);
+   }
+   }
+
+   for (tlbsel = 0; tlbsel  2; tlbsel++) {
+   printk(Shadow TLB%d:\n, tlbsel);
+   for (i = 0; i  vcpu_e500-shadow_tlb_size[tlbsel]; i++) {
+   tlbe = vcpu_e500-shadow_tlb[tlbsel][i];
+   if (tlbe-mas1  MAS1_VALID)
+   printk( S[%d][%3d] |  %08X | %08X | %08X | 
%08X |\n,
+   tlbsel, i, tlbe-mas1, tlbe-mas2,
+   tlbe-mas3, tlbe-mas7);
+   }
+   }
+}
+
+static inline unsigned int tlb0_get_next_victim(
+   struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+   unsigned int victim;
+
+   victim = vcpu_e500-guest_tlb_nv[0]++;
+   if (unlikely(vcpu_e500-guest_tlb_nv[0] = KVM_E500_TLB0_WAY_NUM))
+   vcpu_e500-guest_tlb_nv[0] = 0;
+
+   return victim;
+}
+
+static inline unsigned int tlb1_max_shadow_size(void)
+{
+   return tlb1_entry_num - tlbcam_index;
+}
+
+static inline int tlbe_is_writable(struct tlbe *tlbe)
+{
+   return tlbe-mas3  (MAS3_SW|MAS3_UW);
+}
+
+static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
+{
+   /* Mask off reserved bits. */
+   mas3 = MAS3_ATTRIB_MASK;
+
+   if (!usermode) {
+   /* Guest is in supervisor mode,
+* so we need to translate guest
+* supervisor permissions into user permissions. */
+   mas3 = ~E500_TLB_USER_PERM_MASK;
+   mas3 |= (mas3  E500_TLB_SUPER_PERM_MASK)  1;
+   }
+
+   return mas3 | E500_TLB_SUPER_PERM_MASK;
+}
+
+static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode)
+{
+   return mas2  MAS2_ATTRIB_MASK;
+}
+
+/*
+ * Writing shadow tlb entry to host TLB
+ */
+static inline void __write_host_tlbe(struct tlbe *stlbe)
+{
+   mtspr(SPRN_MAS1, stlbe-mas1);
+   mtspr(SPRN_MAS2, stlbe-mas2);
+   mtspr(SPRN_MAS3, stlbe-mas3);
+   mtspr(SPRN_MAS7, stlbe-mas7);
+   __asm__ __volatile__ (tlbwe\n : : );
+}
+
+static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
+   int tlbsel, int esel)
+{
+   struct tlbe *stlbe = vcpu_e500-shadow_tlb[tlbsel][esel];
+
+   local_irq_disable();
+   if (tlbsel == 0) {
+   __write_host_tlbe(stlbe);
+   } else {
+   unsigned register mas0;
+
+   mas0 = mfspr(SPRN_MAS0);
+
+   mtspr(SPRN_MAS0, MAS0_TLBSEL(1) | 
MAS0_ESEL(to_htlb1_esel(esel)));
+   __write_host_tlbe(stlbe);
+
+   mtspr(SPRN_MAS0, mas0);
+   }
+   local_irq_enable();
+}
+
+void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu)
+{
+   struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+   int 

RE: [PATCH 07/10] Add kvmppc_mmu_dtlb/itlb_miss for booke

2008-12-18 Thread Liu Yu

 -Original Message-
 From: kvm-ppc-ow...@vger.kernel.org 
 [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Hollis Blanchard
 Sent: Friday, December 19, 2008 7:49 AM
 To: Liu Yu-B13201
 Cc: kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 07/10] Add kvmppc_mmu_dtlb/itlb_miss for booke
 
 I don't think you've supplied an implementation of these 
 hooks for e500.
 Does it build with this patch series applied?
 

Yes. I have git-am all this patch series, rebuilt and retested them.
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html