[PATCH 1 of 2] kvm: ppc: Move 440-specific TLB code into 44x_tlb.c

2008-09-11 Thread Hollis Blanchard
# HG changeset patch
# User Hollis Blanchard [EMAIL PROTECTED]
# Date 1221162418 18000
# Node ID 0f01a4354a6aac06b3fe7062e6d4ee538286c405
# Parent  34089016b7ff30a697fc67753353e893e7351daa
kvm: ppc: Move 440-specific TLB code into 44x_tlb.c

This will make it easier to provide implementations for other cores.

Signed-off-by: Hollis Blanchard [EMAIL PROTECTED]

---
4 files changed, 145 insertions(+), 143 deletions(-)
arch/powerpc/include/asm/kvm_ppc.h |4 -
arch/powerpc/kvm/44x_tlb.c |  138 +++-
arch/powerpc/kvm/booke_guest.c |   26 --
arch/powerpc/kvm/emulate.c |  120 +--

diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -58,11 +58,11 @@ extern int kvmppc_emulate_instruction(st
 extern int kvmppc_emulate_instruction(struct kvm_run *run,
   struct kvm_vcpu *vcpu);
 extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu);
+extern int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws);
+extern int kvmppc_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb, u8 
rc);
 
 extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn,
u64 asid, u32 flags);
-extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
-  gva_t eend, u32 asid);
 extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
 extern void kvmppc_mmu_switch_pid(struct kvm_vcpu *vcpu, u32 pid);
 
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -31,6 +31,34 @@
 #define PPC44x_TLB_SUPER_PERM_MASK (PPC44x_TLB_SX|PPC44x_TLB_SR|PPC44x_TLB_SW)
 
 static unsigned int kvmppc_tlb_44x_pos;
+
+#ifdef DEBUG
+void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
+{
+   struct kvmppc_44x_tlbe *tlbe;
+   int i;
+
+   printk(vcpu %d TLB dump:\n, vcpu-vcpu_id);
+   printk(| %2s | %3s | %8s | %8s | %8s |\n,
+   nr, tid, word0, word1, word2);
+
+   for (i = 0; i  PPC44x_TLB_SIZE; i++) {
+   tlbe = vcpu-arch.guest_tlb[i];
+   if (tlbe-word0  PPC44x_TLB_VALID)
+   printk( G%2d |  %02X | %08X | %08X | %08X |\n,
+  i, tlbe-tid, tlbe-word0, tlbe-word1,
+  tlbe-word2);
+   }
+
+   for (i = 0; i  PPC44x_TLB_SIZE; i++) {
+   tlbe = vcpu-arch.shadow_tlb[i];
+   if (tlbe-word0  PPC44x_TLB_VALID)
+   printk( S%2d | %02X | %08X | %08X | %08X |\n,
+  i, tlbe-tid, tlbe-word0, tlbe-word1,
+  tlbe-word2);
+   }
+}
+#endif
 
 static u32 kvmppc_44x_tlb_shadow_attrib(u32 attrib, int usermode)
 {
@@ -185,8 +213,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcp
handler);
 }
 
-void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
-   gva_t eend, u32 asid)
+static void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
+  gva_t eend, u32 asid)
 {
unsigned int pid = !(asid  0xff);
int i;
@@ -243,3 +271,109 @@ void kvmppc_mmu_priv_switch(struct kvm_v
 
vcpu-arch.shadow_pid = !usermode;
 }
+
+static int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
+ const struct tlbe *tlbe)
+{
+   gpa_t gpa;
+
+   if (!get_tlb_v(tlbe))
+   return 0;
+
+   /* Does it match current guest AS? */
+   /* XXX what about IS != DS? */
+   if (get_tlb_ts(tlbe) != !!(vcpu-arch.msr  MSR_IS))
+   return 0;
+
+   gpa = get_tlb_raddr(tlbe);
+   if (!gfn_to_memslot(vcpu-kvm, gpa  PAGE_SHIFT))
+   /* Mapping is not for RAM. */
+   return 0;
+
+   return 1;
+}
+
+int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
+{
+   u64 eaddr;
+   u64 raddr;
+   u64 asid;
+   u32 flags;
+   struct tlbe *tlbe;
+   unsigned int index;
+
+   index = vcpu-arch.gpr[ra];
+   if (index  PPC44x_TLB_SIZE) {
+   printk(%s: index %d\n, __func__, index);
+   kvmppc_dump_vcpu(vcpu);
+   return EMULATE_FAIL;
+   }
+
+   tlbe = vcpu-arch.guest_tlb[index];
+
+   /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
+   if (tlbe-word0  PPC44x_TLB_VALID) {
+   eaddr = get_tlb_eaddr(tlbe);
+   asid = (tlbe-word0  PPC44x_TLB_TS) | tlbe-tid;
+   kvmppc_mmu_invalidate(vcpu, eaddr, get_tlb_end(tlbe), asid);
+   }
+
+   switch (ws) {
+   case PPC44x_TLB_PAGEID:
+   tlbe-tid = vcpu-arch.mmucr  0xff;
+   tlbe-word0 = vcpu-arch.gpr[rs];
+   break;
+

RE: [PATCH 1 of 2] kvm: ppc: Move 440-specific TLB code into 44x_tlb.c

2008-09-11 Thread Liu Yu-B13201

 @@ -222,6 +130,7 @@ int kvmppc_emulate_instruction(struct kv
   int rc;
   int rs;
   int rt;
 + int ws;
   int sprn;
   int dcrn;
   enum emulation_result emulated = EMULATE_DONE;
 @@ -630,33 +539,18 @@ int kvmppc_emulate_instruction(struct kv
   break;
  
   case 978:   
 /* tlbwe */
 - emulated = kvmppc_emul_tlbwe(vcpu, inst);
 + ra = get_ra(inst);
 + rs = get_rs(inst);
 + ws = get_ws(inst);
 + emulated = kvmppc_emul_tlbwe(vcpu, ra, rs, ws);
   break;

E500 has no argument in instructions tlbwe and tlbsx, different from
44x.
So ra, rs, ws are redundant to e500.
Maybe we can keep the old interface: kvmppc_emul_tlbwe(vcpu, inst),
kvmppc_emul_tlbsx(vcpu, inst)
and move instruction operations get_ra(), get_rs(), get_ws() etc. to a
header file.
What do you think about it?

  
 - case 914:   {   
 /* tlbsx */
 - int index;
 - unsigned int as = get_mmucr_sts(vcpu);
 - unsigned int pid = get_mmucr_stid(vcpu);
 -
 + case 914:   
 /* tlbsx */
   rt = get_rt(inst);
   ra = get_ra(inst);
   rb = get_rb(inst);
   rc = get_rc(inst);
 -
 - ea = vcpu-arch.gpr[rb];
 - if (ra)
 - ea += vcpu-arch.gpr[ra];
 -
 - index = kvmppc_44x_tlb_index(vcpu, ea, pid, as);
 - if (rc) {
 - if (index  0)
 - vcpu-arch.cr = ~0x2000;
 - else
 - vcpu-arch.cr |= 0x2000;
 - }
 - vcpu-arch.gpr[rt] = index;
 -
 - }
 + emulated = kvmppc_emul_tlbsx(vcpu, rt, 
 ra, rb, rc);
   break;
  
   case 790:   
 /* lhbrx */
 


--
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