From patchwork Sat Apr 27 08:08:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 2496811 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork1.kernel.org (Postfix) with ESMTP id CD22E3FC64 for ; Sat, 27 Apr 2013 08:08:59 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UW0Bf-00007V-68; Sat, 27 Apr 2013 08:08:51 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UW0Bc-0002v3-PT; Sat, 27 Apr 2013 08:08:48 +0000 Received: from mail-pb0-x234.google.com ([2607:f8b0:400e:c01::234]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UW0BZ-0002uj-Na for linux-arm-kernel@lists.infradead.org; Sat, 27 Apr 2013 08:08:46 +0000 Received: by mail-pb0-f52.google.com with SMTP id mc17so1174624pbc.39 for ; Sat, 27 Apr 2013 01:08:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=ignLdmow2zJweplI3F8bENLo2ph7kWZOfrYtUl0PQ3w=; b=YkP//yeF4riuOsvb6+bZ/xRZ7QhK9VdpgMxzHbtenOKmXWKyY6eHTtBI/ub+C3n3Kw h6XtQp9N2H7kUo4sgjJCV+IA3VlrRe6Dv14jkozftVNzC8yCoDz0WHPAo7GBTMtvlL/9 yymnP+k5PIJ5eUbYCZ5scPouA7ppLvQ6KDUraBLrkd3aJNXFdOW8v0/nsMT+WMfM8H3S KPXewiPYznVPIKGP/j/jmy89MPLK9jPvPUEhcbXKr05mMmg4hegiNMQUH6q3vefnIDTO W0bzTJhjVAA66qUeBpufD3ffxUtKbnny9zECb6hcqc/A/nwJSCQ3wgKT50rZCfTeF+D9 3hdg== X-Received: by 10.68.99.226 with SMTP id et2mr62045485pbb.91.1367050123553; Sat, 27 Apr 2013 01:08:43 -0700 (PDT) Received: from pnqlab006.amcc.com ([182.72.18.82]) by mx.google.com with ESMTPSA id z8sm14999944pbt.23.2013.04.27.01.08.39 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 27 Apr 2013 01:08:42 -0700 (PDT) From: Anup Patel To: kvmarm@lists.cs.columbia.edu Subject: [PATCH] ARM: KVM: Allow host virt timer irq to be different from guest timer virt irq Date: Sat, 27 Apr 2013 13:38:06 +0530 Message-Id: <1367050086-2902-1-git-send-email-anup.patel@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-Gm-Message-State: ALoCoQkF3Fz7pS6zwtKcaR94QFlQvuyCU2CT0gq7ePMuSn1umqXDMdGdVWujr5KbpMngZ24cAHZc X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130427_040845_964096_121911F4 X-CRM114-Status: GOOD ( 17.40 ) X-Spam-Score: 0.6 (/) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (0.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- 2.5 SUSPICIOUS_RECIPS Similar addresses in recipient list -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: marc.zyngier@arm.com, linaro-kernel@lists.linaro.org, Anup Patel , linux-arm-kernel@lists.infradead.org, Pranavkumar Sawargaonkar X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The arch_timer irq numbers (or PPI numbers) are implementation dependent so, the host virtual timer irq number can be different from guest virtual timer irq number. This patch ensures that host virtual timer irq number is read from DTB and guest virtual timer irq is determined based on vcpu target type. Signed-off-by: Anup Patel Signed-off-by: Pranavkumar Sawargaonkar --- arch/arm/include/asm/kvm_arch_timer.h | 9 +++++++++ arch/arm/kvm/arch_timer.c | 35 ++++++++++++++++++++++++++------- arch/arm/kvm/reset.c | 11 ++++++++++- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/arch/arm/include/asm/kvm_arch_timer.h b/arch/arm/include/asm/kvm_arch_timer.h index 68cb9e1..51b0316 100644 --- a/arch/arm/include/asm/kvm_arch_timer.h +++ b/arch/arm/include/asm/kvm_arch_timer.h @@ -61,6 +61,8 @@ struct arch_timer_cpu { #ifdef CONFIG_KVM_ARM_TIMER int kvm_timer_hyp_init(void); int 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); void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu); @@ -76,7 +78,14 @@ static inline int kvm_timer_init(struct kvm *kvm) return 0; } +int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, + const struct kvm_irq_level *irq) +{ + return 0; +} + static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} + static inline void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) {} static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {} static inline void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) {} diff --git a/arch/arm/kvm/arch_timer.c b/arch/arm/kvm/arch_timer.c index 49a7516..c07b63c 100644 --- a/arch/arm/kvm/arch_timer.c +++ b/arch/arm/kvm/arch_timer.c @@ -30,7 +30,7 @@ static struct timecounter *timecounter; static struct workqueue_struct *wqueue; -static struct kvm_irq_level timer_irq = { +static struct kvm_irq_level host_timer_irq = { .level = 1, }; @@ -67,8 +67,8 @@ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu) timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK; kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, - vcpu->arch.timer_cpu.irq->irq, - vcpu->arch.timer_cpu.irq->level); + timer->irq->irq, + timer->irq->level); } static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) @@ -156,6 +156,27 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) timer_arm(timer, ns); } +int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, + const struct kvm_irq_level *irq) +{ + struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; + + /* + * The vcpu timer irq number cannot be determined in + * kvm_timer_vcpu_init() because it is called much before + * kvm_vcpu_set_target(). To handle this, we determine + * vcpu timer irq number when the vcpu is resetted. + */ + timer->irq = irq; + + /* + * Make sure timer is disarmed. + */ + timer_disarm(timer); + + return 0; +} + void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; @@ -163,12 +184,12 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) INIT_WORK(&timer->expired, kvm_timer_inject_irq_work); hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); timer->timer.function = kvm_timer_expire; - timer->irq = &timer_irq; + timer->irq = NULL; } static void kvm_timer_init_interrupt(void *info) { - enable_percpu_irq(timer_irq.irq, 0); + enable_percpu_irq(host_timer_irq.irq, 0); } @@ -182,7 +203,7 @@ static int kvm_timer_cpu_notify(struct notifier_block *self, break; case CPU_DYING: case CPU_DYING_FROZEN: - disable_percpu_irq(timer_irq.irq); + disable_percpu_irq(host_timer_irq.irq); break; } @@ -230,7 +251,7 @@ int kvm_timer_hyp_init(void) goto out; } - timer_irq.irq = ppi; + host_timer_irq.irq = ppi; err = register_cpu_notifier(&kvm_timer_cpu_nb); if (err) { diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c index b80256b..148397e 100644 --- a/arch/arm/kvm/reset.c +++ b/arch/arm/kvm/reset.c @@ -26,6 +26,7 @@ #include #include #include +#include /****************************************************************************** * Cortex-A15 Reset Values @@ -37,6 +38,11 @@ static struct kvm_regs a15_regs_reset = { .usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT, }; +static struct kvm_irq_level a15_timer_irq = { + .irq = 27, + .level = 1, +}; + /******************************************************************************* * Exported reset function @@ -52,6 +58,7 @@ static struct kvm_regs a15_regs_reset = { int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { struct kvm_regs *cpu_reset; + const struct kvm_irq_level *cpu_irq; switch (vcpu->arch.target) { case KVM_ARM_TARGET_CORTEX_A15: @@ -59,6 +66,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) return -EINVAL; cpu_reset = &a15_regs_reset; vcpu->arch.midr = read_cpuid_id(); + cpu_irq = &a15_timer_irq; break; default: return -ENODEV; @@ -70,5 +78,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) /* Reset CP15 registers */ kvm_reset_coprocs(vcpu); - return 0; + /* Reset arch_timer context */ + return kvm_timer_vcpu_reset(vcpu, cpu_irq); }