From patchwork Mon May 21 05:24:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Guo X-Patchwork-Id: 917403 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=kvm-ppc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bjGqbm+k"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40q7RR2vBMz9s71 for ; Mon, 21 May 2018 16:00:19 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751079AbeEUGAS (ORCPT ); Mon, 21 May 2018 02:00:18 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:36466 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751058AbeEUGAS (ORCPT ); Mon, 21 May 2018 02:00:18 -0400 Received: by mail-pf0-f193.google.com with SMTP id w129-v6so6547513pfd.3; Sun, 20 May 2018 23:00:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qnEYrJrIIF0/ea/MZrUvASeVYmf5v219xi4UTRVx+Hs=; b=bjGqbm+kvtLG+Uwhxf7sU10HoAIlctGHpDnQch05WRU7OejtEzDU8ffUGM4B3Dk9nr NgIDLLn9HSZy2P//gsjVI4bXnSnQ1QIXfRXfKhydvrMCJAi15mFX/tGloAtzO+46G00o Jgjzha08Zhtg0u3SqPwISL2Kj39Q672QCrOY8P60E35sZuwqEZXnz83p4xYR6A3JIC5u Yu8FulledRbnOrDIabM9fEI1fd+l6IHAnNlqu5onBKbYkuTab7QHRVCdDDhPUAMNehNT mFGCBPT2mk16WdWwRlpWyqoNwqAvRkLlUtj+Dvuv4uMOD+hLf6eCF96MAf2EAFwsJAKA PO9Q== 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=qnEYrJrIIF0/ea/MZrUvASeVYmf5v219xi4UTRVx+Hs=; b=OSm06Dk7Jd9UA8zh6xF5g4Wwangje1PW7F07IAhmFZ1ULqvHgaURyMxk/j8gxZUYWc 0naoRHVbPT1Diz/TqvBmp95Z9ObRhm9iyuznfLuaMGpJPTogblPiWdcIkdwX8U5P4TNd /SBDRIF8k1G+63VKKHfovAwyAI3TDlRUZbocQipFKe4WuKrIn/zDHG3wcyOc+2XZ5hJ2 HA+m1k4Ej8W9A1SRWgYiSYSROEkkGyKHPRACVTk+bHWvV/9galmGfHLY3jA4V286GZ9U nJe9p/OU/AtfSzCa3W1k/cUALv5ySf2TIG7/PU5xlTqIR2E/9IQSaTI34g5QfTQEwbca +VNw== X-Gm-Message-State: ALKqPwcsyLc6fTq6XjRfXvebhGqqpHbKxq+8NtMmenAUcXpdtgjot430 lAmEI3bEuTv7l2c6kKn/P6kBjw== X-Google-Smtp-Source: AB8JxZqL2J4gGIqSB4yct23TWp+ryc0MTvs0qqafgrBipypgivRYV1gipey8pi7FfkYuuF+L/BKt5w== X-Received: by 2002:a65:6205:: with SMTP id d5-v6mr14764889pgv.416.1526882417246; Sun, 20 May 2018 23:00:17 -0700 (PDT) Received: from simonLocalRHEL7.cn.ibm.com ([112.73.0.89]) by smtp.gmail.com with ESMTPSA id g76-v6sm24424203pfj.102.2018.05.20.23.00.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 May 2018 23:00:16 -0700 (PDT) From: wei.guo.simon@gmail.com To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , kvm@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, Simon Guo Subject: [PATCH v3 4/7] KVM: PPC: reimplement LOAD_FP/STORE_FP instruction mmio emulation with analyse_intr() input Date: Mon, 21 May 2018 13:24:23 +0800 Message-Id: <1526880266-11291-5-git-send-email-wei.guo.simon@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1526880266-11291-1-git-send-email-wei.guo.simon@gmail.com> References: <1526880266-11291-1-git-send-email-wei.guo.simon@gmail.com> Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org From: Simon Guo This patch reimplements LOAD_FP/STORE_FP instruction MMIO emulation with analyse_intr() input. It utilizes the FPCONV/UPDATE properties exported by analyse_instr() and invokes kvmppc_handle_load(s)/kvmppc_handle_store() accordingly. For FP store MMIO emulation, the FP regs need to be flushed firstly so that the right FP reg vals can be read from vcpu->arch.fpr, which will be stored into MMIO data. Suggested-by: Paul Mackerras Signed-off-by: Simon Guo --- arch/powerpc/kvm/emulate_loadstore.c | 201 ++++++++--------------------------- 1 file changed, 44 insertions(+), 157 deletions(-) diff --git a/arch/powerpc/kvm/emulate_loadstore.c b/arch/powerpc/kvm/emulate_loadstore.c index af7c71a..5d38f95 100644 --- a/arch/powerpc/kvm/emulate_loadstore.c +++ b/arch/powerpc/kvm/emulate_loadstore.c @@ -138,6 +138,26 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu) break; } +#ifdef CONFIG_PPC_FPU + case LOAD_FP: + if (kvmppc_check_fp_disabled(vcpu)) + return EMULATE_DONE; + + if (op.type & FPCONV) + vcpu->arch.mmio_sp64_extend = 1; + + if (op.type & SIGNEXT) + emulated = kvmppc_handle_loads(run, vcpu, + KVM_MMIO_REG_FPR|op.reg, size, 1); + else + emulated = kvmppc_handle_load(run, vcpu, + KVM_MMIO_REG_FPR|op.reg, size, 1); + + if ((op.type & UPDATE) && (emulated != EMULATE_FAIL)) + kvmppc_set_gpr(vcpu, op.update_reg, op.ea); + + break; +#endif case STORE: /* if need byte reverse, op.val has been reversed by * analyse_instr(). @@ -149,6 +169,30 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu) kvmppc_set_gpr(vcpu, op.update_reg, op.ea); break; +#ifdef CONFIG_PPC_FPU + case STORE_FP: + if (kvmppc_check_fp_disabled(vcpu)) + return EMULATE_DONE; + + /* The FP registers need to be flushed so that + * kvmppc_handle_store() can read actual FP vals + * from vcpu->arch. + */ + if (vcpu->kvm->arch.kvm_ops->giveup_ext) + vcpu->kvm->arch.kvm_ops->giveup_ext(vcpu, + MSR_FP); + + if (op.type & FPCONV) + vcpu->arch.mmio_sp64_extend = 1; + + emulated = kvmppc_handle_store(run, vcpu, + VCPU_FPR(vcpu, op.reg), size, 1); + + if ((op.type & UPDATE) && (emulated != EMULATE_FAIL)) + kvmppc_set_gpr(vcpu, op.update_reg, op.ea); + + break; +#endif case CACHEOP: /* Do nothing. The guest is performing dcbi because * hardware DMA is not snooped by the dcache, but @@ -170,93 +214,6 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu) switch (get_op(inst)) { case 31: switch (get_xop(inst)) { -#ifdef CONFIG_PPC_FPU - case OP_31_XOP_LFSX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - vcpu->arch.mmio_sp64_extend = 1; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 4, 1); - break; - - case OP_31_XOP_LFSUX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - vcpu->arch.mmio_sp64_extend = 1; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 4, 1); - kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); - break; - - case OP_31_XOP_LFDX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 8, 1); - break; - - case OP_31_XOP_LFDUX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 8, 1); - kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); - break; - - case OP_31_XOP_LFIWAX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_loads(run, vcpu, - KVM_MMIO_REG_FPR|rt, 4, 1); - break; - - case OP_31_XOP_LFIWZX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 4, 1); - break; - - case OP_31_XOP_STFSX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - vcpu->arch.mmio_sp64_extend = 1; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), 4, 1); - break; - - case OP_31_XOP_STFSUX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - vcpu->arch.mmio_sp64_extend = 1; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), 4, 1); - kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); - break; - - case OP_31_XOP_STFDX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), 8, 1); - break; - - case OP_31_XOP_STFDUX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), 8, 1); - kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); - break; - - case OP_31_XOP_STFIWX: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), 4, 1); - break; -#endif - #ifdef CONFIG_VSX case OP_31_XOP_LXSDX: if (kvmppc_check_vsx_disabled(vcpu)) @@ -421,76 +378,6 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu) } break; -#ifdef CONFIG_PPC_FPU - case OP_STFS: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - vcpu->arch.mmio_sp64_extend = 1; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), - 4, 1); - break; - - case OP_STFSU: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - vcpu->arch.mmio_sp64_extend = 1; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), - 4, 1); - kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); - break; - - case OP_STFD: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), - 8, 1); - break; - - case OP_STFDU: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_store(run, vcpu, - VCPU_FPR(vcpu, rs), - 8, 1); - kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); - break; - - case OP_LFS: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - vcpu->arch.mmio_sp64_extend = 1; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 4, 1); - break; - - case OP_LFSU: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - vcpu->arch.mmio_sp64_extend = 1; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 4, 1); - kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); - break; - - case OP_LFD: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 8, 1); - break; - - case OP_LFDU: - if (kvmppc_check_fp_disabled(vcpu)) - return EMULATE_DONE; - emulated = kvmppc_handle_load(run, vcpu, - KVM_MMIO_REG_FPR|rt, 8, 1); - kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); - break; -#endif - default: emulated = EMULATE_FAIL; break;