RE: [PATCH 05/11] E500 core-specific code

2008-12-15 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: Tuesday, December 16, 2008 7:03 AM
> To: Liu Yu-B13201
> Cc: kvm-ppc@vger.kernel.org
> Subject: Re: [PATCH 05/11] E500 core-specific code
> 
> (By the way, I know you split these patches because they're different
> files, but since patch 5 can't possibly work (or even build) without
> patches 6 and 7, they should be joined together.)
> 
> On Thu, 2008-12-11 at 17:11 +0800, Liu Yu wrote:
> > +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, as);
> 
> Why are you discarding pid here? Which brings up the next 
> point, from a
> later patch:

My mistake...
Fixed. Thanks.

> 
> > +int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,
> > +   gva_t eaddr, int as)
> > +{
> > +   struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> > +   int esel, tlbsel;
> > +
> > +   for (tlbsel = 0; tlbsel < 2; tlbsel++) {
> > +   esel = e500_tlb_index(vcpu_e500, eaddr, tlbsel,
> > +   get_cur_pid(vcpu), as);
> > +   if (esel >= 0)
> > +   return index_of(tlbsel, esel);
> > +   }
> > +
> > +   return -1;
> > +}
> 
> You can't possibly search a TLB without knowing the EA, AS, *and* PID.
> accordingly, PID should be a parameter to this function.
> 
> Now, if you told me you wanted to support e500's multiple PID 
> registers,
> I could understand that's something of an interface issue. But you're
> not, so...
> 
> By the way, do you happen to know if any major operating systems use
> PID1 or PID2?

Seems no operating system uses them.
E500-mc core has already removed them...

But head_fsl_booke.S accesses PID1 and PID2 at _start just in order to
clear 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


Re: [PATCH 05/11] E500 core-specific code

2008-12-15 Thread Hollis Blanchard
(By the way, I know you split these patches because they're different
files, but since patch 5 can't possibly work (or even build) without
patches 6 and 7, they should be joined together.)

On Thu, 2008-12-11 at 17:11 +0800, Liu Yu wrote:
> +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, as);

Why are you discarding pid here? Which brings up the next point, from a
later patch:

> +int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,
> +   gva_t eaddr, int as)
> +{
> +   struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> +   int esel, tlbsel;
> +
> +   for (tlbsel = 0; tlbsel < 2; tlbsel++) {
> +   esel = e500_tlb_index(vcpu_e500, eaddr, tlbsel,
> +   get_cur_pid(vcpu), as);
> +   if (esel >= 0)
> +   return index_of(tlbsel, esel);
> +   }
> +
> +   return -1;
> +}

You can't possibly search a TLB without knowing the EA, AS, *and* PID.
accordingly, PID should be a parameter to this function.

Now, if you told me you wanted to support e500's multiple PID registers,
I could understand that's something of an interface issue. But you're
not, so...

By the way, do you happen to know if any major operating systems use
PID1 or PID2?

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


[PATCH 05/11] E500 core-specific code

2008-12-11 Thread Liu Yu
Signed-off-by: Liu Yu <[EMAIL PROTECTED]>
---
 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, <[EMAIL PROTECTED]>
+ *
+ * Description:
+ * This file is derived from arch/powerpc/include/asm/kvm_44x.h,
+ * by Hollis Blanchard <[EMAIL PROTECTED]>.
+ *
+ * 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 
+
+#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..b1950ff
--- /dev/null
+++ b/arch/powerpc/kvm/e500.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, <[EMAIL PROTECTED]>
+ *
+ * Description:
+ * This file is derived from arch/powerpc/kvm/44x.c,
+ * by Hollis Blanchard <[EMAIL PROTECTED]>.
+ *
+ * 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 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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, 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 = kvm_vcpu_init(vcpu, kvm, id);
+   if (err)
+   goto free_vcpu;
+
+   err =