From patchwork Sat Dec 26 21:56:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Smarduch X-Patchwork-Id: 7922581 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BC0EE9F387 for ; Sat, 26 Dec 2015 21:59:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CE3FD202D1 for ; Sat, 26 Dec 2015 21:59:27 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AD65220212 for ; Sat, 26 Dec 2015 21:59:26 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aCwqm-0002Yw-Cl; Sat, 26 Dec 2015 21:58:08 +0000 Received: from mailout4.w2.samsung.com ([211.189.100.14] helo=usmailout4.samsung.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aCwq2-0001lV-KI for linux-arm-kernel@lists.infradead.org; Sat, 26 Dec 2015 21:57:27 +0000 Received: from uscpsbgm2.samsung.com (u115.gpu85.samsung.co.kr [203.254.195.115]) by usmailout4.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NZZ00CRPJN11T20@usmailout4.samsung.com> for linux-arm-kernel@lists.infradead.org; Sat, 26 Dec 2015 16:57:01 -0500 (EST) X-AuditID: cbfec373-f79d26d000001dd9-18-567f0d2d7644 Received: from ussync4.samsung.com ( [203.254.195.84]) by uscpsbgm2.samsung.com (USCPMTA) with SMTP id 32.A6.07641.D2D0F765; Sat, 26 Dec 2015 16:57:01 -0500 (EST) Received: from sisasmtp.sisa.samsung.com ([105.144.21.116]) by ussync4.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NZZ009LWJN1T100@ussync4.samsung.com>; Sat, 26 Dec 2015 16:57:01 -0500 (EST) Received: from localhost.localdomain (105.160.5.6) by SISAEX02SJ.sisa.samsung.com (105.144.21.116) with Microsoft SMTP Server (TLS) id 14.3.224.2; Sat, 26 Dec 2015 13:57:00 -0800 From: Mario Smarduch To: kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org, marc.zyngier@arm.com Subject: [PATCH v6 6/6] arm/arm64: KVM: Enable armv8 fp/simd enhanced context switch Date: Sat, 26 Dec 2015 13:56:56 -0800 Message-id: <1451167016-3787-1-git-send-email-m.smarduch@samsung.com> X-Mailer: git-send-email 1.9.1 MIME-version: 1.0 X-Originating-IP: [105.160.5.6] X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsVy+t/hEF1d3vowg+evDCxevP7HaDFnaqHF x1PH2S02Pb7GavH3zj82B1aPNfPWMHrcubaHzeP8pjXMHpuX1Ht83iQXwBrFZZOSmpNZllqk b5fAlTHr0BfGgocKFVO3RTYwTpbuYuTkkBAwkZi0ZAUbhC0mceHeeiCbi0NIYAmjROfJ9UwQ TguTxKH+FihnG6PEg2eXWUBa2AR0Jfbf28gOYosIhEpMWf6aCcRmFsiQmP30H1hcWCBM4vHv BmYQm0VAVWL5t1uMIDavgKvEow/NLBCr5SROHpvMChEXlPgx+R5QnANojoTE889KIGEhoNZt N58zQpTLS2zZ3sY+gVFgFpKOWQgdCxiZVjGKlhYnFxQnpeca6RUn5haX5qXrJefnbmKEhGzx DsYXG6wOMQpwMCrx8E54VhsmxJpYVlyZe4hRgoNZSYS38mpdmBBvSmJlVWpRfnxRaU5q8SFG aQ4WJXHeVFafUCGB9MSS1OzU1ILUIpgsEwenVANj9Onu7+cXLJy/7MbHhVs3X67MXnr6iELH tu4Vdz58cz7hdCL+kWWXmHzwNa7e6zVdjv0F03bukbG8drv+25NDxpcMCvrcEoXWv76wo2vr L4uH/q96FptMl8n4f9WJ2dts00OG5BmzlbT6bCxu7yzvCjx30+lnVOKf5akBPfqz56mV1pQ/ s8++pMRSnJFoqMVcVJwIANVMPolVAgAA X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151226_135723_136930_31935F26 X-CRM114-Status: GOOD ( 12.74 ) X-Spam-Score: -6.9 (------) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org, Mario Smarduch Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Enable armv8 enhanced fp/simd context switch. Guest and host registers are only context switched on first access and vcpu put. Signed-off-by: Mario Smarduch --- arch/arm/kvm/arm.c | 13 +++++++++++-- arch/arm64/kernel/asm-offsets.c | 1 + arch/arm64/kvm/hyp/entry.S | 1 + arch/arm64/kvm/hyp/switch.c | 26 ++------------------------ 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index b16ed98..633a208 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -316,10 +316,19 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { /* If the fp/simd registers are dirty save guest, restore host. */ - if (vcpu_vfp_isdirty(vcpu)) + if (vcpu_vfp_isdirty(vcpu)) { + vcpu_restore_host_vfp_state(vcpu); - /* Restore host FPEXC trashed in vcpu_load */ + /* + * For 32bit guest on arm64 save the guest fpexc register + * in EL2 mode. + */ + if (vcpu_guest_is_32bit(vcpu)) + vcpu_save_fpexc(vcpu); + } + + /* For arm32 restore host FPEXC trashed in vcpu_load. */ vcpu_restore_host_fpexc(vcpu); /* diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 94090a6..d69145c 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -112,6 +112,7 @@ int main(void) DEFINE(VCPU_ESR_EL2, offsetof(struct kvm_vcpu, arch.fault.esr_el2)); DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2)); DEFINE(VCPU_HPFAR_EL2, offsetof(struct kvm_vcpu, arch.fault.hpfar_el2)); + DEFINE(VCPU_CPTR_EL2, offsetof(struct kvm_vcpu, arch.cptr_el2)); DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context)); #endif #ifdef CONFIG_CPU_PM diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S index fd0fbe9..ce7e903 100644 --- a/arch/arm64/kvm/hyp/entry.S +++ b/arch/arm64/kvm/hyp/entry.S @@ -136,6 +136,7 @@ ENTRY(__fpsimd_guest_restore) isb mrs x3, tpidr_el2 + str w2, [x3, #VCPU_CPTR_EL2] ldr x0, [x3, #VCPU_HOST_CONTEXT] kern_hyp_va x0 diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index ca8f5a5..962d179 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c @@ -19,24 +19,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu) { - u64 val; - - /* - * We are about to set CPTR_EL2.TFP to trap all floating point - * register accesses to EL2, however, the ARM ARM clearly states that - * traps are only taken to EL2 if the operation would not otherwise - * trap to EL1. Therefore, always make sure that for 32-bit guests, - * we set FPEXC.EN to prevent traps to EL1, when setting the TFP bit. - */ - val = vcpu->arch.hcr_el2; - if (!(val & HCR_RW)) { - write_sysreg(1 << 30, fpexc32_el2); - isb(); - } - write_sysreg(val, hcr_el2); + write_sysreg(vcpu->arch.hcr_el2, hcr_el2); /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */ write_sysreg(1 << 15, hstr_el2); - write_sysreg(CPTR_EL2_TTA | CPTR_EL2_TFP, cptr_el2); + write_sysreg(vcpu->arch.cptr_el2, cptr_el2); write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); } @@ -89,7 +75,6 @@ static int __hyp_text __guest_run(struct kvm_vcpu *vcpu) { struct kvm_cpu_context *host_ctxt; struct kvm_cpu_context *guest_ctxt; - bool fp_enabled; u64 exit_code; vcpu = kern_hyp_va(vcpu); @@ -119,8 +104,6 @@ static int __hyp_text __guest_run(struct kvm_vcpu *vcpu) exit_code = __guest_enter(vcpu, host_ctxt); /* And we're baaack! */ - fp_enabled = __fpsimd_enabled(); - __sysreg_save_state(guest_ctxt); __sysreg32_save_state(vcpu); __timer_save_state(vcpu); @@ -131,11 +114,6 @@ static int __hyp_text __guest_run(struct kvm_vcpu *vcpu) __sysreg_restore_state(host_ctxt); - if (fp_enabled) { - __fpsimd_save_state(&guest_ctxt->gp_regs.fp_regs); - __fpsimd_restore_state(&host_ctxt->gp_regs.fp_regs); - } - __debug_save_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt); __debug_cond_restore_host_state(vcpu);