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

2008-09-12 Thread Hollis Blanchard
On Fri, 2008-09-12 at 10:59 +0800, Liu Yu-B13201 wrote:
> 
> > @@ -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.

I thought about that, but get_ra/rs/ws are all specific to instruction
emulation, so I'd rather keep them in emulate.c. (In fact they're static
inlines in that file.)

Also, they are trivial to calculate (like 1 instruction each), so I
don't think it's worth trying to avoid them. If the e500 implementation
of kvmppc_emul_tlbwe() doesn't actually use them, so what? Basically I
think the parameters to the per-core hook functions should be the union
of the parameters required by every hook implementation. In places where
some of those parameters are very expensive to calculate, it would make
sense to avoid it, but this isn't one of those instances.

Along those same lines, from our other discussion around the TLB miss
handler, I would be fine with keeping two variables: TLB_index and
TLB_select, where TLB_select happens always to be 0 on 440. In that
particular case, it just so happens that it's very easy to combine them
into a single integer, so we don't need to have two after all... but
philosophically I'd be happy with it.

-- 
Hollis Blanchard
IBM Linux Technology Center

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


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


[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;
+