From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexander Graf Date: Thu, 19 May 2011 10:43:21 +0000 Subject: Re: [PATCH 09/13] KVM: PPC: e500: enable magic page Message-Id: <4DD4F449.907@suse.de> List-Id: References: <20110517234234.GG3580@schlenkerla.am.freescale.net> In-Reply-To: <20110517234234.GG3580@schlenkerla.am.freescale.net> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: kvm-ppc@vger.kernel.org On 05/18/2011 01:42 AM, Scott Wood wrote: > This is a shared page used for paravirtualization. It is always present > in the guest kernel's effective address space at the address indicated > by the hypercall that enables it. > > The physical address specified by the hypercall is not used, as > e500 does not have real mode. This also requires a documentation change. > Signed-off-by: Scott Wood > --- > arch/powerpc/include/asm/kvm_ppc.h | 1 + > arch/powerpc/kvm/booke.c | 11 +++++++++++ > arch/powerpc/kvm/e500_tlb.c | 22 +++++++++++++++++++++- > arch/powerpc/kvm/powerpc.c | 9 +++++---- > 4 files changed, 38 insertions(+), 5 deletions(-) > > diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h > index 9345238..c662f14 100644 > --- a/arch/powerpc/include/asm/kvm_ppc.h > +++ b/arch/powerpc/include/asm/kvm_ppc.h > @@ -109,6 +109,7 @@ extern void kvmppc_booke_exit(void); > > extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu); > extern int kvmppc_kvm_pv(struct kvm_vcpu *vcpu); > +extern void kvmppc_map_magic(struct kvm_vcpu *vcpu); > > /* > * Cuts out inst bits with ordering according to spec. > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c > index 85b9391..036625e 100644 > --- a/arch/powerpc/kvm/booke.c > +++ b/arch/powerpc/kvm/booke.c > @@ -472,6 +472,17 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, > gpa_t gpaddr; > gfn_t gfn; > > +#ifdef CONFIG_KVM_E500 > + if (!(vcpu->arch.shared->msr& MSR_PR)&& > + (eaddr& PAGE_MASK) = vcpu->arch.magic_page_ea) { > + kvmppc_map_magic(vcpu); > + kvmppc_account_exit(vcpu, DTLB_VIRT_MISS_EXITS); > + r = RESUME_GUEST; > + > + break; > + } > +#endif > + > /* Check the guest TLB. */ > gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr); > if (gtlb_index< 0) { > diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c > index 7f808c5..c09e642 100644 > --- a/arch/powerpc/kvm/e500_tlb.c > +++ b/arch/powerpc/kvm/e500_tlb.c > @@ -76,7 +76,8 @@ static inline unsigned int tlb0_get_next_victim( > > static inline unsigned int tlb1_max_shadow_size(void) > { > - return tlb1_entry_num - tlbcam_index; > + /* reserve one entry for magic page */ > + return tlb1_entry_num - tlbcam_index - 1; > } > > static inline int tlbe_is_writable(struct tlbe *tlbe) > @@ -142,6 +143,25 @@ static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500, > } > } > > +void kvmppc_map_magic(struct kvm_vcpu *vcpu) > +{ > + struct tlbe magic; > + ulong shared_page = ((ulong)vcpu->arch.shared)& PAGE_MASK; > + pfn_t pfn; > + > + pfn = (pfn_t)virt_to_phys((void *)shared_page)>> PAGE_SHIFT; > + get_page(pfn_to_page(pfn)); > + > + magic.mas1 = MAS1_VALID | MAS1_TS | > + MAS1_TSIZE(BOOK3E_PAGESZ_4K); > + magic.mas2 = vcpu->arch.magic_page_ea | MAS2_M; > + magic.mas3 = (pfn<< PAGE_SHIFT) | > + MAS3_SW | MAS3_SR | MAS3_UW | MAS3_UR; > + magic.mas7 = pfn>> (32 - PAGE_SHIFT); > + > + __write_host_tlbe(&magic, MAS0_TLBSEL(1) | MAS0_ESEL(tlbcam_index)); It's a 4k page, so why use TLB1? Also, you add this as PID0 mapping, no? Shouldn't it be restricted to the guest's kernel? Alex