Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp1090070imm; Wed, 11 Jul 2018 17:07:51 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdttWbyZGgZSITo+bh2fz2nniwWVMu/LnzO/3xC5aOP/xsxzNrAGpx9bime47DRLcohpWJL X-Received: by 2002:a62:5d55:: with SMTP id r82-v6mr17831pfb.150.1531354071050; Wed, 11 Jul 2018 17:07:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531354071; cv=none; d=google.com; s=arc-20160816; b=w9mG5pmod1DOnWSAX3KCV3m2WhCS3/DsXdLsZuS9ICTU4UjwmA+TXTR3ChVwXUPeop DNNcyrGJcbwZeAw5jTdZhVLL7MNVh8qqtoQq5UDQxarQPPR/K0INh8NWBfZUV0FTZoIO worp9qdu3xQct4CaOgQtrApiYLOWVAvup2QNFaTAqmJRCaf1a82EnIvkg+u+ZdeEUhEC Zoj65ayRjdBHUqoEgI98i2EcD5LOWtEVD+YvgI3U9C4gGmzeP7lq2ICalR7rYqkoUJZc H3+cVzn7X3qEMsc1bwZfsr1Z0ovfANIS4fKmvt0KwOe9D67NJVwGVsBAP81sFzVhqhOi tyAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=hsyJynAoXgUmiXmqXBErHKHqVXAVkablaYphgOJTO7A=; b=Bl66K4cYBqd14An7AJu8gpN7NV6y+vTK4gI7fC0Ugo9i1THW+BdonqJg+h8XSQSvvU zAU700bM7yGqsgS+4/HscoochJ5FOYJDJDKIqgK0a6tlKoHTE5RlKH4J59p0af+q1DCY LMotzZ3J93Agq3VNqigfYEDCJWRAOpmvuj9HJ8ktmM/3Mja7BCP9mmg6MRBJ7zErcD9I pb6ajDJB/n8UZoQPqb1rVtSR7YdtpOT2jB8mcDFDaOPEPvIK740GL+Epy+IU4kXYetI1 u7sPFmR1UiPNC3sBgL77NiEjB+nEHXUhI/SCQf1ygHADATwlW3h8I+mgEfa5CcZFmJd8 6apQ== ARC-Authentication-Results: i=1; mx.google.com; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k188-v6si20213633pgc.321.2018.07.11.17.07.35; Wed, 11 Jul 2018 17:07:51 -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; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388809AbeGKRmn (ORCPT + 99 others); Wed, 11 Jul 2018 13:42:43 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:50088 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1732492AbeGKRmn (ORCPT ); Wed, 11 Jul 2018 13:42:43 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 24E097C6CA; Wed, 11 Jul 2018 17:37:21 +0000 (UTC) Received: from vitty.brq.redhat.com (unknown [10.43.2.155]) by smtp.corp.redhat.com (Postfix) with ESMTP id 82246111AF36; Wed, 11 Jul 2018 17:37:19 +0000 (UTC) From: Vitaly Kuznetsov To: kvm@vger.kernel.org Cc: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , x86@kernel.org, Andy Lutomirski , "Dmitry V . Levin" , Masatake YAMATO , linux-kernel@vger.kernel.org Subject: [PATCH] x86/kvm/vmx: don't read current->thread.{fs,gs}base of legacy tasks Date: Wed, 11 Jul 2018 19:37:18 +0200 Message-Id: <20180711173718.8850-1-vkuznets@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Wed, 11 Jul 2018 17:37:21 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Wed, 11 Jul 2018 17:37:21 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'vkuznets@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When we switched from doing rdmsr() to reading FS/GS base values from current->thread we completely forgot about legacy 32-bit userspaces which we still support in KVM (why?). task->thread.{fsbase,gsbase} are only synced for 64-bit processes, calling save_fsgs_for_kvm() and using its result from current is illegal for legacy processes. There's no ARCH_SET_FS/GS prctls for legacy applications. Base MSRs are, however, not always equal to zero. Intel's manual says (3.4.4 Segment Loading Instructions in IA-32e Mode): "In order to set up compatibility mode for an application, segment-load instructions (MOV to Sreg, POP Sreg) work normally in 64-bit mode. An entry is read from the system descriptor table (GDT or LDT) and is loaded in the hidden portion of the segment register. ... The hidden descriptor register fields for FS.base and GS.base are physically mapped to MSRs in order to load all address bits supported by a 64-bit implementation. " The issue was found by strace test suite where 32-bit ioctl_kvm_run test started segfaulting. Reported-by: Dmitry V. Levin Bisected-by: Masatake YAMATO Fixes: 42b933b59721 ("x86/kvm/vmx: read MSR_{FS,KERNEL_GS}_BASE from current->thread") Signed-off-by: Vitaly Kuznetsov --- arch/x86/kvm/vmx.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 559a12b6184d..65968649b365 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2560,6 +2560,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) struct vcpu_vmx *vmx = to_vmx(vcpu); #ifdef CONFIG_X86_64 int cpu = raw_smp_processor_id(); + unsigned long fsbase, kernel_gsbase; #endif int i; @@ -2575,12 +2576,20 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel; #ifdef CONFIG_X86_64 - save_fsgs_for_kvm(); - vmx->host_state.fs_sel = current->thread.fsindex; - vmx->host_state.gs_sel = current->thread.gsindex; -#else - savesegment(fs, vmx->host_state.fs_sel); - savesegment(gs, vmx->host_state.gs_sel); + if (likely(is_64bit_mm(current->mm))) { + save_fsgs_for_kvm(); + vmx->host_state.fs_sel = current->thread.fsindex; + vmx->host_state.gs_sel = current->thread.gsindex; + fsbase = current->thread.fsbase; + kernel_gsbase = current->thread.gsbase; + } else { +#endif + savesegment(fs, vmx->host_state.fs_sel); + savesegment(gs, vmx->host_state.gs_sel); +#ifdef CONFIG_X86_64 + fsbase = read_msr(MSR_FS_BASE); + kernel_gsbase = read_msr(MSR_KERNEL_GS_BASE); + } #endif if (!(vmx->host_state.fs_sel & 7)) { vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel); @@ -2600,10 +2609,10 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) savesegment(ds, vmx->host_state.ds_sel); savesegment(es, vmx->host_state.es_sel); - vmcs_writel(HOST_FS_BASE, current->thread.fsbase); + vmcs_writel(HOST_FS_BASE, fsbase); vmcs_writel(HOST_GS_BASE, cpu_kernelmode_gs_base(cpu)); - vmx->msr_host_kernel_gs_base = current->thread.gsbase; + vmx->msr_host_kernel_gs_base = kernel_gsbase; if (is_long_mode(&vmx->vcpu)) wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); #else -- 2.14.4