Received: by 2002:a89:48b:0:b0:1f5:f2ab:c469 with SMTP id a11csp1305511lqd; Thu, 25 Apr 2024 11:17:05 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVkSIJAH352U4jm8OQjEWDRf5HDN+kqLyGBvGiuB6MNCGBnjBXRaajJnu0aPukXIoGOcxSjnHuqNrll8Z2nb0EXwYv9R60wG7fhT3ukmA== X-Google-Smtp-Source: AGHT+IFDIR5kv8i9KzQGHVl/xf9h1OZwtQpqc3EVkXOpBtCUJGN8nHSjmABkX8Y943Wxp9jnecBC X-Received: by 2002:a17:902:694b:b0:1ea:cc:b59e with SMTP id k11-20020a170902694b00b001ea00ccb59emr411996plt.19.1714069024772; Thu, 25 Apr 2024 11:17:04 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714069024; cv=pass; d=google.com; s=arc-20160816; b=Euko2s9DMG/E9XhqS3MG+ShVSnqt2dwB5J6qzKqbWd/F4b+MpSyGXGtpnq2FpWV6Pd e3HBlrdg+X2WKUhTkvHINf/pSpNFKh3/t7wrVreCH81oY2dd4WIi9r70PQdSOdLGIa3l AC5VVxMTlaVOlv9eCLtDLqes/OclfvTc57zruROAGnFUrAUZCimWzZGf9Zf6k2edMpSX ma2gcLo2LyE5cMi+LVEV5hA7Z+PnlKRCa0ZGzsq4t6Uvraz2FlsZBkjawpM25eA5iChg UQ8f2pUYToIz/aVbf5dmfbDp2k0V0DDr8FV2eA3v2nw9xLZNkWrnB6yBLz4Y46OzbLLE 3D2Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :reply-to:dkim-signature; bh=iXAD1gTtiwO6R5kc5FsGGbiVN1kl1k4gITxMp5dXiKA=; fh=gYEmRxJSrHWOb5CtVSj1kcEkXRNBzyL/rRqb1ROP4bw=; b=esCl5KEG/KH8Gl8Sb42abZiHfhRGdNqvlATq4fFdKf25tQW6W/1f0JYtoO1AHQ818a dvK1iOFM2RJvtv6p3PJluEGKZ9AueoezvsFAmIpxcjeX5ZQbcJ8rbYL85TDAxMNY8h8S bo2+7NCri1YRoRfoHQyRqv2p+/FPcQ1SpsO6cc15myMzIugV9k6dwHl9Pj5wDdsjqqEg sfGcit96nqG2K2hSXEPPpY+bvYxq7ooA3vqgN5E7RkdK2/fW206wLsF0YeCF01LupH5O aQxKuhuehPMPemudeOjT/M82xR5c0X2t1vwv5Q/0Fc+Kqu39o9ebdNDQnDxM2fGS3Jb7 9odg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=eDAfGkxY; arc=pass (i=1 spf=pass spfdomain=flex--seanjc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-159006-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-159006-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id n6-20020a170902f60600b001defa2d6abasi14334410plg.71.2024.04.25.11.17.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Apr 2024 11:17:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-159006-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=eDAfGkxY; arc=pass (i=1 spf=pass spfdomain=flex--seanjc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-159006-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-159006-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 6062C282494 for ; Thu, 25 Apr 2024 18:17:04 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AA991156238; Thu, 25 Apr 2024 18:14:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="eDAfGkxY" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1B03D15574E for ; Thu, 25 Apr 2024 18:14:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714068883; cv=none; b=EyGlvj4sOx6rpNGtWPVR3CemY8Aym1SetLrL3T1AbAVk85ybFj/ADTD3KuA5M5vcSWyp+jTiMAhBsIVfdWeq44ieBF6RybruDKoNFtDHwnBtwwILbr83VnljkL1cMAJTPbUXFL83Db+b64edl4anzqgz+BCGK/AkWqMaJQbn3F4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714068883; c=relaxed/simple; bh=XQbuCE10iEXL6Hj41mbGLp/9CQA2+KEDclppIVQzUqI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NwUq0nzgNvkEsSr9+OKWun8VW+7Vgtj2HI5HFAV9Tv+EAS+oKYq6MyuFHu2ueTjbVwDhHtZuZntCiNw2g4A5W/SShi0rbQe3kJCnldQSmgdmQAP6pgaENYL3sWKIc5oxR2GzVum3GQgUKupacKol9xy1YuDyy+3IyoTHvBacSPw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=eDAfGkxY; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-de59e612376so838968276.3 for ; Thu, 25 Apr 2024 11:14:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1714068881; x=1714673681; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=iXAD1gTtiwO6R5kc5FsGGbiVN1kl1k4gITxMp5dXiKA=; b=eDAfGkxYy589HlReu2v+v08ULFTE4L3nA7ftceBq/ImSOM76BJzAUpdvc1MNml4n7w V/mi9B06kW/rRx0U9zQJw7izsrek0FlhNT2mPLWxCe0roEjOiPveIaT1X5bm4PpcDDap m4K7SrI1pbjfjrlM8H9JnCQ9tfBlR5kb1FFlElcUDZhoMxOsZtVQVc5tugIdjzBEbmc4 UEs6VV3FQs4eyv+hPNcBAVueCp9k6pjnULvxl8CeGu0dCVAIbSQDBMi94tvfrY0VgizL Sig8zYO4L8sYK9HnTLmhrTPgPVwAdYrE+8CiJU6M3ZKy//JWnIkJ0ZVcaXny+BlaYYVP NwfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714068881; x=1714673681; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=iXAD1gTtiwO6R5kc5FsGGbiVN1kl1k4gITxMp5dXiKA=; b=nAzIAHNXIRvahFoW4pu94UHAQij8Clsbq8kDPgNbNAzhdHErn8IMpcyZs7XtNYlGzn NjUOXzxXVUPzMyRptq4yxRg1XDE9v6VRuCGkR+pR/pgztwVCpQULr38mcaqmrGqUccwb UozNIKvKDdGuAQdoHMy1J89RfbAvka6qozs4DUrVHKGbs+Anm+q0ODRI35cqYwVp68lq ZmruExyJTIc2++QJk5k7uU5oRmjdcOsvoqM7TQ9/dVlWDQTBBQyOnraKG+hfhN7jEbxw TIKtqjXAuzQrdw68SOxeHbx94OL+C0Fu4Dtu2QB019/ggcWdNVcLBSKgk3tECWv3q5S+ xK4Q== X-Forwarded-Encrypted: i=1; AJvYcCXMhQfSF+7DpeIXAIy7zv7onnPtKdAG99ZnbW0zEtQ8WiAwxTPZdEjAZKW10LFuXiP+3ibdvlNl46TIt7L/lMEj6BnGi4zPhSKZO7mL X-Gm-Message-State: AOJu0Yz9jYy0cv9damDOmBVzhGAB2oq9w1PzK/h4n7y6IGFu6a/WMNeI gEeo+1NgWK5828enj3RuApexXp1NFLRul2g0rmGDdzfjqFZRjzQVHpVLvDI8diWiYfNXZdbpQKO odw== X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a05:6902:1006:b0:dcd:3a37:65 with SMTP id w6-20020a056902100600b00dcd3a370065mr55877ybt.7.1714068881182; Thu, 25 Apr 2024 11:14:41 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 25 Apr 2024 11:14:19 -0700 In-Reply-To: <20240425181422.3250947-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240425181422.3250947-1-seanjc@google.com> X-Mailer: git-send-email 2.44.0.769.g3c40516874-goog Message-ID: <20240425181422.3250947-8-seanjc@google.com> Subject: [PATCH 07/10] KVM: x86: Funnel all fancy MSR return value handling into a common helper From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Tom Lendacky , Weijiang Yang Content-Type: text/plain; charset="UTF-8" Add a common helper, kvm_do_msr_access(), to invoke the "leaf" APIs that are type and access specific, and more importantly to handle errors that are returned from the leaf APIs. I.e. turn kvm_msr_ignored_check() from a a helper that is called on an error, into a trampoline that detects errors *and* applies relevant side effects, e.g. logging unimplemented accesses. Because the leaf APIs are used for guest accesses, userspace accesses, and KVM accesses, and because KVM supports restricting access to MSRs from userspace via filters, the error handling is subtly non-trivial. E.g. KVM has had at least one bug escape due to making each "outer" function handle errors. See commit 3376ca3f1a20 ("KVM: x86: Fix KVM_GET_MSRS stack info leak"). Signed-off-by: Sean Christopherson --- arch/x86/kvm/x86.c | 86 +++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c0727df18e92..a0506878d58e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -319,25 +319,40 @@ u64 __read_mostly host_xcr0; static struct kmem_cache *x86_emulator_cache; -/* - * When called, it means the previous get/set msr reached an invalid msr. - * Return true if we want to ignore/silent this failed msr access. - */ -static bool kvm_msr_ignored_check(u32 msr, u64 data, bool write) +typedef int (*msr_access_t)(struct kvm_vcpu *vcpu, u32 index, u64 *data, + bool host_initiated); + +static __always_inline int kvm_do_msr_access(struct kvm_vcpu *vcpu, u32 msr, + u64 *data, bool host_initiated, + enum kvm_msr_access rw, + msr_access_t msr_access_fn) { - const char *op = write ? "wrmsr" : "rdmsr"; - - if (ignore_msrs) { - if (report_ignored_msrs) - kvm_pr_unimpl("ignored %s: 0x%x data 0x%llx\n", - op, msr, data); - /* Mask the error */ - return true; - } else { + const char *op = rw == MSR_TYPE_W ? "wrmsr" : "rdmsr"; + int ret; + + BUILD_BUG_ON(rw != MSR_TYPE_R && rw != MSR_TYPE_W); + + /* + * Zero the data on read failures to avoid leaking stack data to the + * guest and/or userspace, e.g. if the failure is ignored below. + */ + ret = msr_access_fn(vcpu, msr, data, host_initiated); + if (ret && rw == MSR_TYPE_R) + *data = 0; + + if (ret != KVM_MSR_RET_UNSUPPORTED) + return ret; + + if (!ignore_msrs) { kvm_debug_ratelimited("unhandled %s: 0x%x data 0x%llx\n", - op, msr, data); - return false; + op, msr, *data); + return ret; } + + if (report_ignored_msrs) + kvm_pr_unimpl("ignored %s: 0x%x data 0x%llx\n", op, msr, *data); + + return 0; } static struct kmem_cache *kvm_alloc_emulator_cache(void) @@ -1705,16 +1720,8 @@ static int kvm_get_feature_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, static int do_get_feature_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) { - int r; - - /* Unconditionally clear the output for simplicity */ - *data = 0; - r = kvm_get_feature_msr(vcpu, index, data, true); - - if (r == KVM_MSR_RET_UNSUPPORTED && kvm_msr_ignored_check(index, 0, false)) - r = 0; - - return r; + return kvm_do_msr_access(vcpu, index, data, true, MSR_TYPE_R, + kvm_get_feature_msr); } static bool __kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer) @@ -1901,16 +1908,17 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data, return static_call(kvm_x86_set_msr)(vcpu, &msr); } +static int _kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, + bool host_initiated) +{ + return __kvm_set_msr(vcpu, index, *data, host_initiated); +} + static int kvm_set_msr_ignored_check(struct kvm_vcpu *vcpu, u32 index, u64 data, bool host_initiated) { - int ret = __kvm_set_msr(vcpu, index, data, host_initiated); - - if (ret == KVM_MSR_RET_UNSUPPORTED) - if (kvm_msr_ignored_check(index, data, true)) - ret = 0; - - return ret; + return kvm_do_msr_access(vcpu, index, &data, host_initiated, MSR_TYPE_W, + _kvm_set_msr); } /* @@ -1949,16 +1957,8 @@ int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, static int kvm_get_msr_ignored_check(struct kvm_vcpu *vcpu, u32 index, u64 *data, bool host_initiated) { - int ret = __kvm_get_msr(vcpu, index, data, host_initiated); - - if (ret == KVM_MSR_RET_UNSUPPORTED) { - /* Unconditionally clear *data for simplicity */ - *data = 0; - if (kvm_msr_ignored_check(index, 0, false)) - ret = 0; - } - - return ret; + return kvm_do_msr_access(vcpu, index, data, host_initiated, MSR_TYPE_R, + __kvm_get_msr); } static int kvm_get_msr_with_filter(struct kvm_vcpu *vcpu, u32 index, u64 *data) -- 2.44.0.769.g3c40516874-goog