From patchwork Fri Feb 3 15:20:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jintack Lim X-Patchwork-Id: 9554361 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 87F0C602B7 for ; Fri, 3 Feb 2017 15:21:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8481927F9C for ; Fri, 3 Feb 2017 15:21:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7936E2823D; Fri, 3 Feb 2017 15:21:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00 autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E650C27F9C for ; Fri, 3 Feb 2017 15:21:35 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cZfg7-0001P0-5O; Fri, 03 Feb 2017 15:21:35 +0000 Received: from outprodmail02.cc.columbia.edu ([128.59.72.51]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cZff7-0008NO-Eq for linux-arm-kernel@lists.infradead.org; Fri, 03 Feb 2017 15:20:43 +0000 Received: from hazelnut (hazelnut.cc.columbia.edu [128.59.213.250]) by outprodmail02.cc.columbia.edu (8.14.4/8.14.4) with ESMTP id v13FI7BO025845 for ; Fri, 3 Feb 2017 10:20:13 -0500 Received: from hazelnut (localhost.localdomain [127.0.0.1]) by hazelnut (Postfix) with ESMTP id 3291580 for ; Fri, 3 Feb 2017 10:20:13 -0500 (EST) Received: from sendprodmail03.cc.columbia.edu (sendprodmail03.cc.columbia.edu [128.59.72.15]) by hazelnut (Postfix) with ESMTP id 1185E8A for ; Fri, 3 Feb 2017 10:20:13 -0500 (EST) Received: from mail-qk0-f198.google.com (mail-qk0-f198.google.com [209.85.220.198]) by sendprodmail03.cc.columbia.edu (8.14.4/8.14.4) with ESMTP id v13FKC3n046621 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NOT) for ; Fri, 3 Feb 2017 10:20:12 -0500 Received: by mail-qk0-f198.google.com with SMTP id i34so629580qkh.6 for ; Fri, 03 Feb 2017 07:20:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=k41aJNaoTVE/8p1pZaWijVMGqbPqWCdLINjXAhYgzD0=; b=nvwo3Zl/0sJYeJTp2yH4kadfgo5WDArOxVXFpipWi/dOe1Cz5ENpRSeSkIWBu/isHn Yqmn59MStrEa7a+GoilNCZwkdecV796i0dFstYG96ImTp20sBAQWnpF0Z74mN/Xi+VOM 3WJatVI5WDAr7dVMcZhZE0LvUpfqtue9LsoTh5J6TkGxRdmltKlaOD5VQezqDyBu+g9g nNAfbzfSJZsKNgQBn7hcE3Kr1yUHj+hKUDAYHOg336LJOHCacAdZ4A/bMGk2p17OVETX xVGiFzOjB1Uc2k8oz+ybfYHQvB9FLCa963AKkvHyDjjRDT7F8n+XnSpx7z2gweBcW5h5 yLVQ== X-Gm-Message-State: AIkVDXL4yxG0pi5j158kzLM+dzXQJfINcPV3RZSDrefNCkhCZvibWXP8eSSlTkTkTgtXz7HFwLsPI50L0hiOuZq80kZnFmciy9+6eUnDQBZCOz45+U87uU2YNSbihkkc2Bye6sUD/zb/GJrLY2bPlXlfHnen6ZlgCQkkTA== X-Received: by 10.237.44.228 with SMTP id g91mr13510747qtd.184.1486135212552; Fri, 03 Feb 2017 07:20:12 -0800 (PST) X-Received: by 10.237.44.228 with SMTP id g91mr13510701qtd.184.1486135212254; Fri, 03 Feb 2017 07:20:12 -0800 (PST) Received: from jintack.cs.columbia.edu ([2001:18d8:ffff:16:21a:4aff:feaa:f900]) by smtp.gmail.com with ESMTPSA id t35sm24462204qtc.40.2017.02.03.07.20.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Feb 2017 07:20:11 -0800 (PST) From: Jintack Lim To: pbonzini@redhat.com, rkrcmar@redhat.com, christoffer.dall@linaro.org, marc.zyngier@arm.com, linux@armlinux.org.uk, catalin.marinas@arm.com, will.deacon@arm.com, andre.przywara@arm.com, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org Subject: [RFC v4 02/10] KVM: arm/arm64: Move cntvoff to each timer context Date: Fri, 3 Feb 2017 10:20:00 -0500 Message-Id: <1486135208-13415-3-git-send-email-jintack@cs.columbia.edu> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1486135208-13415-1-git-send-email-jintack@cs.columbia.edu> References: <1486135208-13415-1-git-send-email-jintack@cs.columbia.edu> X-No-Spam-Score: Local X-Scanned-By: MIMEDefang 2.78 on 128.59.72.15 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170203_072033_786464_7E07DB9F X-CRM114-Status: GOOD ( 17.84 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jintack@cs.columbia.edu MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Make cntvoff per each timer context. This is helpful to abstract kvm timer functions to work with timer context without considering timer types (e.g. physical timer or virtual timer). This also would pave the way for ever doing adjustments of the cntvoff on a per-CPU basis if that should ever make sense. Signed-off-by: Jintack Lim Signed-off-by: Christoffer Dall --- arch/arm/include/asm/kvm_host.h | 3 --- arch/arm/kvm/arm.c | 1 - arch/arm64/include/asm/kvm_host.h | 3 --- include/kvm/arm_arch_timer.h | 9 +++------ virt/kvm/arm/arch_timer.c | 38 ++++++++++++++++++++++++++++---------- virt/kvm/arm/hyp/timer-sr.c | 3 +-- 6 files changed, 32 insertions(+), 25 deletions(-) diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index d5423ab..cc495d79 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -60,9 +60,6 @@ struct kvm_arch { /* The last vcpu id that ran on each physical CPU */ int __percpu *last_vcpu_ran; - /* Timer */ - struct arch_timer_kvm timer; - /* * Anything that is not used directly from assembly code goes * here. diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 9d74464..f93f2171 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -135,7 +135,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) goto out_free_stage2_pgd; kvm_vgic_early_init(kvm); - kvm_timer_init(kvm); /* Mark the initial VMID generation invalid */ kvm->arch.vmid_gen = 0; diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e505038..4a758cb 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -70,9 +70,6 @@ struct kvm_arch { /* Interrupt controller */ struct vgic_dist vgic; - - /* Timer */ - struct arch_timer_kvm timer; }; #define KVM_NR_MEM_OBJS 40 diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index daad3c1..2c8560b 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -23,11 +23,6 @@ #include #include -struct arch_timer_kvm { - /* Virtual offset */ - u64 cntvoff; -}; - struct arch_timer_context { /* Registers: control register, timer value */ u32 cnt_ctl; @@ -38,6 +33,9 @@ struct arch_timer_context { /* Active IRQ state caching */ bool active_cleared_last; + + /* Virtual offset */ + u64 cntvoff; }; struct arch_timer_cpu { @@ -58,7 +56,6 @@ struct arch_timer_cpu { int kvm_timer_hyp_init(void); int kvm_timer_enable(struct kvm_vcpu *vcpu); -void kvm_timer_init(struct kvm *kvm); int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, const struct kvm_irq_level *irq); void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index d3556b3..5004a67 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -101,9 +101,10 @@ static void kvm_timer_inject_irq_work(struct work_struct *work) static u64 kvm_timer_compute_delta(struct kvm_vcpu *vcpu) { u64 cval, now; + struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); - cval = vcpu_vtimer(vcpu)->cnt_cval; - now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; + cval = vtimer->cnt_cval; + now = kvm_phys_timer_read() - vtimer->cntvoff; if (now < cval) { u64 ns; @@ -159,7 +160,7 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu) return false; cval = vtimer->cnt_cval; - now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; + now = kvm_phys_timer_read() - vtimer->cntvoff; return cval <= now; } @@ -354,10 +355,32 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, return 0; } +/* Make the updates of cntvoff for all vtimer contexts atomic */ +static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff) +{ + int i; + struct kvm *kvm = vcpu->kvm; + struct kvm_vcpu *tmp; + + mutex_lock(&kvm->lock); + kvm_for_each_vcpu(i, tmp, kvm) + vcpu_vtimer(tmp)->cntvoff = cntvoff; + + /* + * When called from the vcpu create path, the CPU being created is not + * included in the loop above, so we just set it here as well. + */ + vcpu_vtimer(vcpu)->cntvoff = cntvoff; + mutex_unlock(&kvm->lock); +} + void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; + /* Synchronize cntvoff across all vtimers of a VM. */ + update_vtimer_cntvoff(vcpu, kvm_phys_timer_read()); + INIT_WORK(&timer->expired, kvm_timer_inject_irq_work); hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); timer->timer.function = kvm_timer_expire; @@ -377,7 +400,7 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) vtimer->cnt_ctl = value; break; case KVM_REG_ARM_TIMER_CNT: - vcpu->kvm->arch.timer.cntvoff = kvm_phys_timer_read() - value; + update_vtimer_cntvoff(vcpu, kvm_phys_timer_read() - value); break; case KVM_REG_ARM_TIMER_CVAL: vtimer->cnt_cval = value; @@ -398,7 +421,7 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) case KVM_REG_ARM_TIMER_CTL: return vtimer->cnt_ctl; case KVM_REG_ARM_TIMER_CNT: - return kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; + return kvm_phys_timer_read() - vtimer->cntvoff; case KVM_REG_ARM_TIMER_CVAL: return vtimer->cnt_cval; } @@ -510,11 +533,6 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) return 0; } -void kvm_timer_init(struct kvm *kvm) -{ - kvm->arch.timer.cntvoff = kvm_phys_timer_read(); -} - /* * On VHE system, we only need to configure trap on physical timer and counter * accesses in EL0 and EL1 once, not for every world switch. diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c index 0cf0895..4734915 100644 --- a/virt/kvm/arm/hyp/timer-sr.c +++ b/virt/kvm/arm/hyp/timer-sr.c @@ -53,7 +53,6 @@ void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu) void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu) { - struct kvm *kvm = kern_hyp_va(vcpu->kvm); struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); u64 val; @@ -71,7 +70,7 @@ void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu) } if (timer->enabled) { - write_sysreg(kvm->arch.timer.cntvoff, cntvoff_el2); + write_sysreg(vtimer->cntvoff, cntvoff_el2); write_sysreg_el0(vtimer->cnt_cval, cntv_cval); isb(); write_sysreg_el0(vtimer->cnt_ctl, cntv_ctl);