Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp846519yba; Wed, 24 Apr 2019 10:32:23 -0700 (PDT) X-Google-Smtp-Source: APXvYqybqpBdDlDjlw5uBEI9IYwC2pw0BgSAwQD3vKh0X0JoR+eHGG+JzWMsEBubO/W/Q85uBDJS X-Received: by 2002:a62:e90b:: with SMTP id j11mr34181553pfh.118.1556127143853; Wed, 24 Apr 2019 10:32:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556127143; cv=none; d=google.com; s=arc-20160816; b=cg+yDRbaPAY3VMyHZ/KGPW0shNtRAqzOh7egbn/J9D34POHJA22Ep7Br5KJom0MeW2 pAMbnXniOBOEWJp2DhHZboaCA9Zneo2WM9d2SFLVmCW0WlbzLveqo2vcAu/ycMQwbqp2 Z+RZm2pBNs1RFhHH8LtT1KNRZXVWX/DlePPNe991Pxf7ty5YIQIN+vrpsxdcbip8i8If +perr0xwTDRy2LbNJ2NX4xUQX+qsIFqQyjGjNCSOev/8HWNK/jujbCB9/kRT0nEBt6fL VI1lhA487cROtXFd3/Kwxok+DyeQw8/NDbggStgEKCXny107MnQBJWl9dU0JDX8qjfDm DzaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=4zpQaZetKxHYuFQxPx8GxMAHVzuAq98FD/kIHwj4Xio=; b=xnqCfFzp8lzJh9SEI1x9JdF+XXzBoaswci3YoHbF4rPg+UuoyN/+aTiTkUz2yC5p6C 4iGpSAwEzMGH6V5XDPRDR3o5sA9f4z8IVjYfcJn4z8CQSR0KCrW5TYxDWA/+z+9fnAF/ WTWJv1KY7gW6n3PumOvRqppYGFFLL7t0iGh+cMRlHjwrU/O+k18XR4aygJUw3ye4ngL7 vHCpTKmoX+NCk1fRfcnnLjyap7yF1EOwL/+lSYGz1js9S6CAYEBbOxPD6Mbn9gFfJpsV ok2gREoqrOfQLE10ixW+/PNbIfQaMTBqpcYA/oG0M12T+UREST8iDymNK7HC8HhwvFbq BMcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=JWKUTgUQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q9si18319913pgq.393.2019.04.24.10.32.08; Wed, 24 Apr 2019 10:32:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=JWKUTgUQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390665AbfDXRac (ORCPT + 99 others); Wed, 24 Apr 2019 13:30:32 -0400 Received: from mail.kernel.org ([198.145.29.99]:56776 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390646AbfDXRa0 (ORCPT ); Wed, 24 Apr 2019 13:30:26 -0400 Received: from localhost (62-193-50-229.as16211.net [62.193.50.229]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 57CAA21905; Wed, 24 Apr 2019 17:30:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1556127025; bh=k8kZ/rdabEIaL6X3zj89Im8ZfKHj1V0Jp9gUE0tRMgU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JWKUTgUQY0kva8tGTrV44VUf7VRogkoLuCgDHQ8cD1kLxDMTv5HNCX+K1SPpj2Oy6 +3VlpF5/ElWihgQSz70MHj8epJM/IeJs6/Hv+kFIS2v/THtmAk4ul2lrG/avVOe2jp GsbqxGWg0YQXYr1FoEkxg+NNrT6Inqp1DbLQ4t5Y= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Sean Christopherson , Paolo Bonzini Subject: [PATCH 4.19 32/96] KVM: x86: Dont clear EFER during SMM transitions for 32-bit vCPU Date: Wed, 24 Apr 2019 19:09:37 +0200 Message-Id: <20190424170922.061765861@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190424170919.829037226@linuxfoundation.org> References: <20190424170919.829037226@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sean Christopherson commit 8f4dc2e77cdfaf7e644ef29693fa229db29ee1de upstream. Neither AMD nor Intel CPUs have an EFER field in the legacy SMRAM save state area, i.e. don't save/restore EFER across SMM transitions. KVM somewhat models this, e.g. doesn't clear EFER on entry to SMM if the guest doesn't support long mode. But during RSM, KVM unconditionally clears EFER so that it can get back to pure 32-bit mode in order to start loading CRs with their actual non-SMM values. Clear EFER only when it will be written when loading the non-SMM state so as to preserve bits that can theoretically be set on 32-bit vCPUs, e.g. KVM always emulates EFER_SCE. And because CR4.PAE is cleared only to play nice with EFER, wrap that code in the long mode check as well. Note, this may result in a compiler warning about cr4 being consumed uninitialized. Re-read CR4 even though it's technically unnecessary, as doing so allows for more readable code and RSM emulation is not a performance critical path. Fixes: 660a5d517aaab ("KVM: x86: save/load state on SMM switch") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/emulate.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2575,15 +2575,13 @@ static int em_rsm(struct x86_emulate_ctx * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU * supports long mode. */ - cr4 = ctxt->ops->get_cr(ctxt, 4); if (emulator_has_longmode(ctxt)) { struct desc_struct cs_desc; /* Zero CR4.PCIDE before CR0.PG. */ - if (cr4 & X86_CR4_PCIDE) { + cr4 = ctxt->ops->get_cr(ctxt, 4); + if (cr4 & X86_CR4_PCIDE) ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE); - cr4 &= ~X86_CR4_PCIDE; - } /* A 32-bit code segment is required to clear EFER.LMA. */ memset(&cs_desc, 0, sizeof(cs_desc)); @@ -2597,13 +2595,16 @@ static int em_rsm(struct x86_emulate_ctx if (cr0 & X86_CR0_PE) ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE)); - /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */ - if (cr4 & X86_CR4_PAE) - ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE); - - /* And finally go back to 32-bit mode. */ - efer = 0; - ctxt->ops->set_msr(ctxt, MSR_EFER, efer); + if (emulator_has_longmode(ctxt)) { + /* Clear CR4.PAE before clearing EFER.LME. */ + cr4 = ctxt->ops->get_cr(ctxt, 4); + if (cr4 & X86_CR4_PAE) + ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE); + + /* And finally go back to 32-bit mode. */ + efer = 0; + ctxt->ops->set_msr(ctxt, MSR_EFER, efer); + } smbase = ctxt->ops->get_smbase(ctxt);