From patchwork Thu Dec 15 12:04:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Mackerras X-Patchwork-Id: 131572 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 2958C10088C for ; Thu, 15 Dec 2011 23:06:05 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758726Ab1LOMGC (ORCPT ); Thu, 15 Dec 2011 07:06:02 -0500 Received: from ozlabs.org ([203.10.76.45]:41564 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758815Ab1LOMGA (ORCPT ); Thu, 15 Dec 2011 07:06:00 -0500 Received: by ozlabs.org (Postfix, from userid 1003) id 90CF81007D6; Thu, 15 Dec 2011 23:05:58 +1100 (EST) Date: Thu, 15 Dec 2011 23:04:18 +1100 From: Paul Mackerras To: Alexander Graf Cc: kvm-ppc@vger.kernel.org, linuxppc-dev@ozlabs.org Subject: [PATCH 5/5] KVM: PPC: Book3s HV: Implement H_CLEAR_REF and H_CLEAR_MOD hcalls Message-ID: <20111215120417.GF20629@bloggs.ozlabs.ibm.com> References: <20111215120018.GA20629@bloggs.ozlabs.ibm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20111215120018.GA20629@bloggs.ozlabs.ibm.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org This adds implementations for the H_CLEAR_REF (test and clear reference bit) and H_CLEAR_MOD (test and clear changed bit) hypercalls. These hypercalls are not used by Linux guests at this stage, and these implementations are only compile tested. Signed-off-by: Paul Mackerras --- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 69 +++++++++++++++++++++++++++++++ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 +- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 76864a8..718b5a7 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -624,6 +624,75 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, return H_SUCCESS; } +long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags, + unsigned long pte_index) +{ + struct kvm *kvm = vcpu->kvm; + unsigned long *hpte, v, r, gr; + struct revmap_entry *rev; + + if (pte_index >= HPT_NPTE) + return H_PARAMETER; + + rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); + hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); + while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) + cpu_relax(); + v = hpte[0]; + r = hpte[1]; + gr = rev->guest_rpte; + rev->guest_rpte &= ~HPTE_R_R; + if (v & HPTE_V_VALID) { + gr |= r & (HPTE_R_R | HPTE_R_C); + if (r & HPTE_R_R) + kvmppc_clear_ref_hpte(kvm, hpte, pte_index); + } + unlock_hpte(hpte, v & ~HPTE_V_HVLOCK); + + if (!(v & (HPTE_V_VALID | HPTE_V_ABSENT))) + return H_NOT_FOUND; + + vcpu->arch.gpr[4] = gr; + return H_SUCCESS; +} + +long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags, + unsigned long pte_index) +{ + struct kvm *kvm = vcpu->kvm; + unsigned long *hpte, v, r, gr; + struct revmap_entry *rev; + + if (pte_index >= HPT_NPTE) + return H_PARAMETER; + + rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); + hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); + while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) + cpu_relax(); + v = hpte[0]; + r = hpte[1]; + gr = rev->guest_rpte; + rev->guest_rpte &= ~HPTE_R_C; + if (v & HPTE_V_VALID) { + gr |= r & (HPTE_R_R | HPTE_R_C); + if (r & HPTE_R_C) { + hpte[0] |= HPTE_V_ABSENT; + kvmppc_invalidate_hpte(kvm, hpte, pte_index); + hpte[1] &= ~HPTE_R_C; + eieio(); + hpte[0] = v; + } + } + unlock_hpte(hpte, v & ~HPTE_V_HVLOCK); + + if (!(v & (HPTE_V_VALID | HPTE_V_ABSENT))) + return H_NOT_FOUND; + + vcpu->arch.gpr[4] = gr; + return H_SUCCESS; +} + void kvmppc_invalidate_hpte(struct kvm *kvm, unsigned long *hptep, unsigned long pte_index) { diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index b70bf22..4c52d6d 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1276,8 +1276,8 @@ hcall_real_table: .long .kvmppc_h_remove - hcall_real_table .long .kvmppc_h_enter - hcall_real_table .long .kvmppc_h_read - hcall_real_table - .long 0 /* 0x10 - H_CLEAR_MOD */ - .long 0 /* 0x14 - H_CLEAR_REF */ + .long .kvmppc_h_clear_mod - hcall_real_table + .long .kvmppc_h_clear_ref - hcall_real_table .long .kvmppc_h_protect - hcall_real_table .long 0 /* 0x1c - H_GET_TCE */ .long .kvmppc_h_put_tce - hcall_real_table