From nobody Thu Oct 2 19:28:01 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 DD6E8287514 for ; Fri, 12 Sep 2025 23:23:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757719412; cv=none; b=KBHTL4yXd8L4J1MCR1jTfVUhjEWM7gwkDGNXIZTCKXCOH4oDCYS8F1EABW/zmVQ7hTWRkQKDJPp9cOtP9TWVaOZj+zbPkqPZRapcP5OWOYTeuZQZH15XXNRKdvH544W/tw9iFR9433DaCcg6WC+jGjJebke7i830o5l6XWar1Ps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757719412; c=relaxed/simple; bh=JgMtGiipAvsajCHzQDSZlw/ojgwsGzJlvzMoyoDNyyg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=TplPEEDFmyJK/dgB4pyWi10f+PB+DkfhOFchMtHoUoGcKIsA82dxz+r8Ck5hTEE6sdTw+hr4PNl8BpghkLLcnrj8laWxh19Ejnks91Ffz2S/mCAvatK6+3xn3kN5vby8/ar0y0Q4OAQjfdc3yWzqWQfa2zU4UQB1Bu5+JyxIDWs= 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=NCh65ll4; arc=none smtp.client-ip=209.85.216.73 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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="NCh65ll4" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-32e0b00138cso179213a91.3 for ; Fri, 12 Sep 2025 16:23:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1757719410; x=1758324210; 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=xbwuOXbdUPdZ5BP99ZPo3T836Bd3RtRn8p0/DAva41U=; b=NCh65ll4DkCqeilv8w6DodpJfy4mCJB9opuy9Z4hl+QRh1+aXk8sL6tO11PKzLfLMY c8zDT8ZiIc7nyRMk61Do7OARIHO1MMvpbp0azadLqki1Zm3G1RcIHfOd1FE7E5LAUQ5L 6r8FE33dtGcA0si2u92o4kSTP2uQRDB1rmXCZZ8O+f3KfXln2JD0rNllbUjQqebitQoJ oAdt49nCVT6xH5dcAqIvKhUgjVjS3SqLvbofv/cxqkZn6byldDly5HSYbiPSdps2QU3q QtfgzZmVG3NLCVaSZfxARJhGnv5u4eNDT91WeeAFwx5hxyrOJ6Le34iPrNqSYynbdQm/ hR7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757719410; x=1758324210; 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=xbwuOXbdUPdZ5BP99ZPo3T836Bd3RtRn8p0/DAva41U=; b=VW68MiZgtpB6FCCJfZVw40A4HCfUpSyUrkc9yZOpWArDUgarBcnt6cKpHKjY92IlvW RnnVg6mZMUYPuPGVtpusdTYvvrQDXHbdO3E2T9cMbucuxsrPkO7T9t4uGZhiiIcDbhdb WW5KpSAEJRgV18AaID92EFU8RY0F665yKykAPI7zxhli0po9oljx09WevouueyLrdJab CfdeCtVDnXIqDtY53rb1UfLqntjIimipKr+P6/6pzt1XrNQ+fpFECdcBhhgjl4z66vVu A8YV7TOLA+wcF4q5ym82L5Nev3Tkkzxd9g9sDFYlyMCu8YY/Y4GJCTCSmqWZ6+rDrKg6 4riw== X-Forwarded-Encrypted: i=1; AJvYcCWp3qyq9JSU6U/WTfdcrqN43UlqABlbgEMY2zspmrh68lL4QNHH6Rk40TTQFgBQitAkod7lKVfbJaTett4=@vger.kernel.org X-Gm-Message-State: AOJu0YwENs3jfA/o0IcDGMfjKJKgL43WC1/0WLQ6ViZUuFWEGcvXo7HU CfMfm6PDh/QZaCY4n5ygGNXP2oYoc+XLZfmz2giz1q58UTuh5vaysISG7iKq9wI/qg1OlQbXzqF 89zAqng== X-Google-Smtp-Source: AGHT+IHq85FsVL5SmVTxL4Oz8O98fzC9mI2W/V9vx9QRJVTsUxxO380i38buUnmI9GAor06pwr2mJlmrR9Y= X-Received: from pjk12.prod.google.com ([2002:a17:90b:558c:b0:327:e7c3:1ffe]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3883:b0:32b:8582:34be with SMTP id 98e67ed59e1d1-32de4ec9af7mr4786721a91.13.1757719410251; Fri, 12 Sep 2025 16:23:30 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 12 Sep 2025 16:22:41 -0700 In-Reply-To: <20250912232319.429659-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: <20250912232319.429659-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.384.g4c02a37b29-goog Message-ID: <20250912232319.429659-4-seanjc@google.com> Subject: [PATCH v15 03/41] KVM: SEV: Validate XCR0 provided by guest in GHCB From: Sean Christopherson To: Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Tom Lendacky , Mathias Krause , John Allen , Rick Edgecombe , Chao Gao , Maxim Levitsky , Xiaoyao Li , Zhang Yi Z Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use __kvm_set_xcr() to propagate XCR0 changes from the GHCB to KVM's software model in order to validate the new XCR0 against KVM's view of the supported XCR0. Allowing garbage is thankfully mostly benign, as kvm_load_{guest,host}_xsave_state() bail early for vCPUs with protected state, xstate_required_size() will simply provide garbage back to the guest, and attempting to save/restore the bad value via KVM_{G,S}ET_XCRS will only harm the guest (setting XCR0 will fail). However, allowing the guest to put junk into a field that KVM assumes is valid is a CVE waiting to happen. And as a bonus, using the proper API eliminates the ugly open coding of setting arch.cpuid_dynamic_bits_dirty. Simply ignore bad values, as either the guest managed to get an unsupported value into hardware, or the guest is misbehaving and providing pure garbage. In either case, KVM can't fix the broken guest. Note, using __kvm_set_xcr() also avoids recomputing dynamic CPUID bits if XCR0 isn't actually changing (relatively to KVM's previous snapshot). Cc: Tom Lendacky Fixes: 291bd20d5d88 ("KVM: SVM: Add initial support for a VMGEXIT VMEXIT") Signed-off-by: Sean Christopherson Reviewed-by: Tom Lendacky --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/svm/sev.c | 6 ++---- arch/x86/kvm/x86.c | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index cb86f3cca3e9..2762554cbb7b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2209,6 +2209,7 @@ int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigne= d long val); unsigned long kvm_get_dr(struct kvm_vcpu *vcpu, int dr); unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw); +int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr); int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu); =20 int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr); diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 37abbda28685..0cd77a87dd84 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -3303,10 +3303,8 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *s= vm) =20 svm->vmcb->save.cpl =3D kvm_ghcb_get_cpl_if_valid(svm, ghcb); =20 - if (kvm_ghcb_xcr0_is_valid(svm)) { - vcpu->arch.xcr0 =3D kvm_ghcb_get_xcr0(ghcb); - vcpu->arch.cpuid_dynamic_bits_dirty =3D true; - } + if (kvm_ghcb_xcr0_is_valid(svm)) + __kvm_set_xcr(vcpu, 0, kvm_ghcb_get_xcr0(ghcb)); =20 /* Copy the GHCB exit information into the VMCB fields */ exit_code =3D kvm_ghcb_get_sw_exit_code(ghcb); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6d85fbafc679..ba4915456615 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1235,7 +1235,7 @@ static inline u64 kvm_guest_supported_xfd(struct kvm_= vcpu *vcpu) } #endif =20 -static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) +int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) { u64 xcr0 =3D xcr; u64 old_xcr0 =3D vcpu->arch.xcr0; @@ -1279,6 +1279,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 i= ndex, u64 xcr) vcpu->arch.cpuid_dynamic_bits_dirty =3D true; return 0; } +EXPORT_SYMBOL_GPL(__kvm_set_xcr); =20 int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu) { --=20 2.51.0.384.g4c02a37b29-goog