From nobody Fri Oct 23 03:30:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 225B040B11C; Thu, 15 Oct 2026 20:21:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095725; cv=none; b=ZDKAb/Bm7iSLoaGzERwIx0qTB947ExP+pucYGOubUwHV/9w9jJ6+uvBaXnksDHXUuriZvTkTCqcbVQ7ikslm40GFXyWbbvOvs7tpBjDEP+MHRYOjwW0ybpP22FcPRVtYytks3YWFmpAQJbyg3y5rblQScSKSeqYhpmmhVLvIGuE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095725; c=relaxed/simple; bh=bEu91svauhluwg9S2y0KXADLiIBC/AB0LG6RjLqH6c0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=trFOT9fIWxI+wh7051iBauBgw3RfX/39qx45s6kt+ZQHfcx2NrnfMbcRS8zwpxiyR4GUCo7IDofbi1SadqlMGLGUm35iOwksnSN9Q1XS2emp8YOyMKtREc3/vyHWUeg7TyRYFgFtc4HZz2kNgU7fIP0lZlS9LxQ+Hd4bnUkahQ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=hFgICQmR; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="hFgICQmR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1792095721; x=1823631721; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bEu91svauhluwg9S2y0KXADLiIBC/AB0LG6RjLqH6c0=; b=hFgICQmRIDkdFPmluNkmDwQwtS2gFR96Mof35lv/yGxwLp4/0AJlPzCt 8fKmg0QzvwsFTe8CuEIsb4dkU/0KA4Y/QzxbZmMJtbL+qvd5LHXCCskcV 9tdmqolIInWPyytqBfhGUsp8NA7K7rIcXS9ojZ/qRVaF2rvWBedpgvPtK /zk3Nu3whL4CpjcJDZh37vXzDNxWM4NxrI4D8qDXD9Z+cePkwoZ7SRvG3 SoBzukRrsYxAmHs+HSh1OdSmKMvk2d9Z5DH7NvbDVKkXC2DeYKgdihENK zZzrZdrFSdxpbtg+D3VS28SeTlS8xmT2TST7/bkNQky38BCw53jU7YXRA A==; X-CSE-ConnectionGUID: XELu0nDGR4+ZVEfAywY6Og== X-CSE-MsgGUID: QudB3Z4LSjePSFFlpdngig== X-IronPort-AV: E=McAfee;i="6800,10657,11936"; a="911082" X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="911082" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Oct 2026 13:21:59 -0700 X-CSE-ConnectionGUID: A78hp7+pSwWlr4McVrY9qQ== X-CSE-MsgGUID: DqlGilf+RgmM7Vb4ceElPQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="1844431" Received: from sohilmeh.sc.intel.com ([172.25.103.65]) by fmviesa003.fm.intel.com with ESMTP; 15 Oct 2026 13:21:57 -0700 From: Sohil Mehta To: kvm@vger.kernel.org, x86@kernel.org Cc: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Shuah Khan , Binbin Wu , Peter Zijlstra , "Chang S . Bae" , Kai Huang , Fuad Tabba , Chao Gao , Yosry Ahmed , Claudio Imbrenda , David Matlack , Bala-Vignesh-Reddy , Kishen Maloor , Rick Edgecombe , Farrah Chen , Sohil Mehta , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v5 1/6] KVM: x86: Add an emulator flag to differentiate branch targets from fetches Date: Thu, 15 Oct 2026 13:19:35 -0700 Message-ID: <20261015201940.1655956-2-sohil.mehta@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261015201940.1655956-1-sohil.mehta@intel.com> References: <20261015201940.1655956-1-sohil.mehta@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Binbin Wu Add a new emulator flag, X86EMUL_F_BRANCH, and use it instead of X86EMUL_F_FETCH in assign_eip() to distinguish between instruction fetch and branch target computation for features that handle them differently. For example, Linear Address Space Separation (LASS) applies to code fetches but not branch target calculations. A LASS violation occurs only when the branch target is used to fetch an instruction. X86EMUL_F_BRANCH is still a code access, so add it to the code segment readability check in __linearize() along with the Linear Address Masking (LAM) untagging exemption in vmx_get_untagged_addr(). For now, X86EMUL_F_BRANCH and X86EMUL_F_FETCH are identical as far as KVM is concerned. No functional change intended. Signed-off-by: Binbin Wu Signed-off-by: Sohil Mehta Tested-by: Kishen Maloor Tested-by: Farrah Chen --- v5: - Picked up Tested-by tags v4: - Added LAM untagging exemption - Reworded the commit message --- arch/x86/kvm/emulate.c | 5 +++-- arch/x86/kvm/kvm_emulate.h | 1 + arch/x86/kvm/vmx/vmx.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c1b21282187f..15872e722af8 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -654,7 +654,8 @@ static __always_inline int __linearize(struct x86_emula= te_ctxt *ctxt, (flags & X86EMUL_F_WRITE)) goto bad; /* unreadable code segment */ - if (!(flags & X86EMUL_F_FETCH) && (desc.type & 8) && !(desc.type & 2)) + if (!(flags & (X86EMUL_F_FETCH | X86EMUL_F_BRANCH)) && + (desc.type & 8) && !(desc.type & 2)) goto bad; lim =3D desc_limit_scaled(&desc); if (!(desc.type & 8) && (desc.type & 4)) { @@ -705,7 +706,7 @@ static inline int assign_eip(struct x86_emulate_ctxt *c= txt, ulong dst) if (ctxt->op_bytes !=3D sizeof(unsigned long)) addr.ea =3D dst & ((1UL << (ctxt->op_bytes << 3)) - 1); rc =3D __linearize(ctxt, addr, &max_size, 1, ctxt->mode, &linear, - X86EMUL_F_FETCH); + X86EMUL_F_BRANCH); if (rc =3D=3D X86EMUL_CONTINUE) ctxt->_eip =3D addr.ea; return rc; diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 10886bea82c9..0623637f923b 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -105,6 +105,7 @@ struct x86_instruction_info { #define X86EMUL_F_INVLPG BIT(3) #define X86EMUL_F_MSR BIT(4) #define X86EMUL_F_DT_LOAD BIT(5) +#define X86EMUL_F_BRANCH BIT(6) =20 struct x86_emulate_ops { void (*vm_bugged)(struct x86_emulate_ctxt *ctxt); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index b341af4c6057..04a9acf4a39a 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8436,7 +8436,8 @@ gva_t vmx_get_untagged_addr(struct kvm_vcpu *vcpu, gv= a_t gva, unsigned int flags int lam_bit; unsigned long cr3_bits; =20 - if (flags & (X86EMUL_F_FETCH | X86EMUL_F_IMPLICIT | X86EMUL_F_INVLPG)) + if (flags & (X86EMUL_F_FETCH | X86EMUL_F_BRANCH | X86EMUL_F_IMPLICIT | + X86EMUL_F_INVLPG)) return gva; =20 if (!is_64_bit_mode(vcpu)) --=20 2.43.0 From nobody Fri Oct 23 03:30:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CE0353E30C; Thu, 15 Oct 2026 20:22:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095723; cv=none; b=BaR5tz6Pi2eliZINdUffhaDZFzV7+3PMa9ZstTgUbASUbgpvZ4cpS/rgTgZ1OpZSeluTgotUOZx4LU6wvtKTz2b9SjyV557Z9ZtdqZXKJwVl6U2QNzBuo4wy2qyNWjvRW6RUQLcegGkuxgb57OxdLuFLOhCVgZRxQ5dzHN4c+k4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095723; c=relaxed/simple; bh=g8FXMCeHZLnxsXsspLx7xhXGvU/3I1ISfwf1ghL1qOU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AMvFLhBrisd1LhM4rPRh54JMJzfDI+zESCaGHL21iz6eixGx4AfTe8E9kJVo3aHX3Ju/jW5o5zYwrv5oLx+jVm1GJDdk8VngSuMGZdAodldpaBaVX31V6fiz8yth9WscNOPS8Ecvg9Cqwdme+PIPCpvSbYKlrdzH5jUvp08kcg0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=f4xVxxP5; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="f4xVxxP5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1792095721; x=1823631721; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=g8FXMCeHZLnxsXsspLx7xhXGvU/3I1ISfwf1ghL1qOU=; b=f4xVxxP5RtxrGBOi2tMDXcxx9Dsv0WUHBCB2Vd+OFX4mWvKTYLy4pp83 xpXcY2jOY1RdG9ai/WsPMO1fafxj+FWiHPGjzbrv/i56qacgGcNtmbPlc o8oTsoqugx0QsGTX3Ss4I72c+X7vXdSnjlqp9ibkqqYKXAJSOnPc0iJws i3QoIungUsdGt7EMLZVpaQXYvS5bAfrOElOdw3TBJunggy3dQ0a+dqzHD CXTPmzUnI4xeETzNYAlpgxPdlQCQUrYYQ9MQ0FwMHxcAmwQ7zVYX66hJo HpYRujlzz8zesHOxSyzI735YIDoUN6TTA7KwMEj58sbxkkmKvtwXEKzJ3 w==; X-CSE-ConnectionGUID: +hXA/PnaQj6RAb8o1CHdow== X-CSE-MsgGUID: F1vOwYSXTFObb0EKV+3rIQ== X-IronPort-AV: E=McAfee;i="6800,10657,11936"; a="911092" X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="911092" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Oct 2026 13:21:59 -0700 X-CSE-ConnectionGUID: 0tS4RtH7S4Sp5oMXFjBX7A== X-CSE-MsgGUID: I4RJ5Fu/QTmlH3tqH4s1Ug== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="1844435" Received: from sohilmeh.sc.intel.com ([172.25.103.65]) by fmviesa003.fm.intel.com with ESMTP; 15 Oct 2026 13:21:58 -0700 From: Sohil Mehta To: kvm@vger.kernel.org, x86@kernel.org Cc: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Shuah Khan , Binbin Wu , Peter Zijlstra , "Chang S . Bae" , Kai Huang , Fuad Tabba , Chao Gao , Yosry Ahmed , Claudio Imbrenda , David Matlack , Bala-Vignesh-Reddy , Kishen Maloor , Rick Edgecombe , Farrah Chen , Sohil Mehta , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v5 2/6] KVM: x86: Use linear_read_system() to read the TSS I/O bitmap Date: Thu, 15 Oct 2026 13:19:36 -0700 Message-ID: <20261015201940.1655956-3-sohil.mehta@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261015201940.1655956-1-sohil.mehta@intel.com> References: <20261015201940.1655956-1-sohil.mehta@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" TSS I/O permission bitmap reads are implicit supervisor accesses which are subject to Linear Address Space Separation (LASS) enforcement. Though highly unlikely, if a guest configures a TSS base in the user half, hardware would raise a #GP on access when LASS is enabled. Currently, the emulator reads the I/O permission bitmap from the TSS by calling read_std() directly which is inconsistent with other implicit accesses in the emulator such as IDT reads, GDT/LDT reads and TSS reads during task switch. An upcoming change will add a check to linear_read_system() to catch LASS violations. For consistency as well as to keep LASS enforcement centralized, switch both I/O bitmap reads to linear_read_system(). Note, emulator_io_port_access_allowed() doesn't propagate faults, so even though linear_read_system() will set the exception details they will be ignored. While at it, fix an off-by-one in the I/O bitmap bounds check to account for the 2-byte read and ensure both bytes are within the TSS limit. The SDM mandates a trailing 0xFF byte after the bitmap so any out-of-bounds access would be all 1s (denying access). Make the change primarily to ensure hardware fidelity. A correctly configured OS will not run into this issue. Signed-off-by: Sohil Mehta Tested-by: Kishen Maloor Tested-by: Farrah Chen --- v5: - Picked up Tested-by tags v4: - New patch There could be a pre-existing issue here. It is unlikely that any OS demand-pages the I/O bitmap portion of the TSS. But if it does, the #PF details could get lost and the guest would get a #GP instead of a restartable #PF. Propagating the #PF to the callers is a larger change that is beyond the scope of this series. --- arch/x86/kvm/emulate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 15872e722af8..fbf47f5ae298 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2555,12 +2555,12 @@ static bool emulator_io_port_access_allowed(struct = x86_emulate_ctxt *ctxt, #ifdef CONFIG_X86_64 base |=3D ((u64)base3) << 32; #endif - r =3D ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL, true); + r =3D linear_read_system(ctxt, base + 102, &io_bitmap_ptr, 2); if (r !=3D X86EMUL_CONTINUE) return false; - if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg)) + if (io_bitmap_ptr + port/8 + 1 > desc_limit_scaled(&tr_seg)) return false; - r =3D ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL, = true); + r =3D linear_read_system(ctxt, base + io_bitmap_ptr + port/8, &perm, 2); if (r !=3D X86EMUL_CONTINUE) return false; if ((perm >> bit_idx) & mask) --=20 2.43.0 From nobody Fri Oct 23 03:30:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 521304E56C8; Thu, 15 Oct 2026 20:22:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095723; cv=none; b=Hx/mCfVJ8rxyY5ZfxS/4Zry5cfxoqVaMy/fuo66qHMchHmN2IBwqvPWDrNhuqS/0tjBlyNVjql8M2/26u+L7jVodF8qysbcarM+nZmef7x7HE3ZRcPKqhHxLcKVHnWKlZXQhYZdG8tqU+oT9ZE9HfY3aXYMPamA3tW4ANxDJ1N8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095723; c=relaxed/simple; bh=Dd7MsmCoV9aXmjakAz8Xoy0iMJDmV7ajQm+CqmYY+2g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ui3su76v0qr4Ye2OlPOnnX3aoM06tnZ4k0eRPpWxtE073lsxdsbnhcEsQCalCc4I7AJbiqM3+5RRHDgvEgZONtZZ20gnwbrVfY+JX/TijZFHRC9+JhYVs+VLRc6ptdL5ljcCvxrTLuhlpGLPRldXjbvxRLkgsi+GShkNqS40HGc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Yf5sjLfK; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Yf5sjLfK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1792095722; x=1823631722; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Dd7MsmCoV9aXmjakAz8Xoy0iMJDmV7ajQm+CqmYY+2g=; b=Yf5sjLfKrZFUf6RXn/E0RpbtvAQzAKwtkMZ3OkKd5DRqBkmfi1N6Hqmk Yw0gt+A9YJpgA//icu0xX4Uy53oEWDFdLXQk5NtAxKrzjIpNlfRpifqY8 uLoe5a/R8NryEtrlUVcS+duv6M/RTjJ/s1kn7V+0FedjH0hoqJh6Hav+O z2bC1KiMqwA+iRQ8JqBvKI41JFXlgXkbqWHJGt2rdUJ+gHOGrq08K1eEL xSteql5zOSA42IGnTyr6+pDj5D7Odx3mcr/qKHqEX7YtlPY7ZXVbnt1/T Dv85+PaAb04GxyD+i5pmpd1vPmB2+Nv4nbu5veNy9YRslmhZ8G+Ch4hrd A==; X-CSE-ConnectionGUID: jZVg+u0YR66uCqv00n+9bw== X-CSE-MsgGUID: FprrIk7pTWemRySY2C4YrA== X-IronPort-AV: E=McAfee;i="6800,10657,11936"; a="911104" X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="911104" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Oct 2026 13:22:00 -0700 X-CSE-ConnectionGUID: qdhylAxKSvyN58cUI/D4zQ== X-CSE-MsgGUID: 5grNBMjJS4yLkW+P9+6Xyw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="1844438" Received: from sohilmeh.sc.intel.com ([172.25.103.65]) by fmviesa003.fm.intel.com with ESMTP; 15 Oct 2026 13:21:58 -0700 From: Sohil Mehta To: kvm@vger.kernel.org, x86@kernel.org Cc: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Shuah Khan , Binbin Wu , Peter Zijlstra , "Chang S . Bae" , Kai Huang , Fuad Tabba , Chao Gao , Yosry Ahmed , Claudio Imbrenda , David Matlack , Bala-Vignesh-Reddy , Kishen Maloor , Rick Edgecombe , Farrah Chen , Sohil Mehta , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v5 3/6] KVM: x86: Add LASS violation checks during instruction emulation Date: Thu, 15 Oct 2026 13:19:37 -0700 Message-ID: <20261015201940.1655956-4-sohil.mehta@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261015201940.1655956-1-sohil.mehta@intel.com> References: <20261015201940.1655956-1-sohil.mehta@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zeng Guang When Linear Address Space Separation (LASS) is enabled, the processor applies a LASS violation check on every access to a linear address. To align with hardware behavior, KVM needs to perform the same check during instruction emulation before consulting the page tables. Add a new callback to x86_emulate_ops to let the emulator query whether an access would trigger a LASS violation. The callback takes the linear address and the size that describe the memory access, plus a set of flags that convey the type of access. Add the LASS violation check to __linearize() so that every explicit guest memory access is validated along with the other linear address checks. The SDM (June 2026), Vol3, Chapter 4, specifically states that there is no relative ordering between the canonicality check and the LASS violation check. Also, there is no prioritization specified between the faults generated by alignment checks and LASS violations. Implicit supervisor accesses bypass __linearize(). So, add LASS checks for those in linear_read_system() and linear_write_system() and tag the access as implicit. For now, emulator_is_lass_violation() is a no-op. Later, it will be wired up to the VMX implementation. Signed-off-by: Zeng Guang Signed-off-by: Sohil Mehta Tested-by: Kishen Maloor Tested-by: Farrah Chen Reviewed-by: Binbin Wu --- v5: - Replaced Binbin's SoB with a Reviewed-by - Picked up Tested-by tags v4: - Switched to using gva_t for the address parameter - Clarified LASS and canonicality checks and alignment checks ordering - Reworded the commit message - Use kvm_x86_call() instead of static_call() Note, internal AI review warned about missing canonicality checks during implicit accesses. A valid guest kernel shouldn't trigger canonicality faults. But for correctness, such checks could be considered. Though, that is beyond the scope of this series. --- arch/x86/include/asm/kvm-x86-ops.h | 1 + arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/emulate.c | 17 +++++++++++++++++ arch/x86/kvm/kvm_emulate.h | 3 ++- arch/x86/kvm/x86.c | 7 +++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-= x86-ops.h index 48fa973b98d5..e16ea56e5911 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -147,6 +147,7 @@ KVM_X86_OP(complete_emulated_msr) KVM_X86_OP(vcpu_deliver_sipi_vector) KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons); KVM_X86_OP_OPTIONAL(get_untagged_addr) +KVM_X86_OP_OPTIONAL_RET0(is_lass_violation) KVM_X86_OP_OPTIONAL(alloc_apic_backing_page) #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT KVM_X86_OP_OPTIONAL_RET0(gmem_make_private) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index e2eef7057bd3..1099ec2801db 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1743,6 +1743,8 @@ struct kvm_x86_ops { unsigned long (*vcpu_get_apicv_inhibit_reasons)(struct kvm_vcpu *vcpu); =20 gva_t (*get_untagged_addr)(struct kvm_vcpu *vcpu, gva_t gva, unsigned int= flags); + bool (*is_lass_violation)(struct kvm_vcpu *vcpu, gva_t gva, + unsigned int size, unsigned int flags); void *(*alloc_apic_backing_page)(struct kvm_vcpu *vcpu); #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT int (*gmem_make_private)(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index fbf47f5ae298..e071b1de1dac 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -675,6 +675,16 @@ static __always_inline int __linearize(struct x86_emul= ate_ctxt *ctxt, } break; } + + /* + * LASS and canonicality checks generate the same fault and their + * relative order is not architecturally defined. Also, the SDM + * doesn't prioritize LASS violations against the misalignment #GP, + * so any order is fine. + */ + if (ctxt->ops->is_lass_violation(ctxt, la, size, flags)) + goto bad; + if (la & (insn_alignment(ctxt, size) - 1)) return emulate_gp(ctxt, 0); return X86EMUL_CONTINUE; @@ -781,6 +791,9 @@ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt= , int rel) static int linear_read_system(struct x86_emulate_ctxt *ctxt, ulong linear, void *data, unsigned size) { + if (ctxt->ops->is_lass_violation(ctxt, linear, size, X86EMUL_F_IMPLICIT)) + return emulate_gp(ctxt, 0); + return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, tr= ue); } =20 @@ -788,6 +801,10 @@ static int linear_write_system(struct x86_emulate_ctxt= *ctxt, ulong linear, void *data, unsigned int size) { + if (ctxt->ops->is_lass_violation(ctxt, linear, size, + X86EMUL_F_IMPLICIT | X86EMUL_F_WRITE)) + return emulate_gp(ctxt, 0); + return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, t= rue); } =20 diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 0623637f923b..c4bd50a28e8a 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -249,7 +249,8 @@ struct x86_emulate_ops { =20 gva_t (*get_untagged_addr)(struct x86_emulate_ctxt *ctxt, gva_t addr, unsigned int flags); - + bool (*is_lass_violation)(struct x86_emulate_ctxt *ctxt, gva_t addr, + unsigned int size, unsigned int flags); bool (*is_canonical_addr)(struct x86_emulate_ctxt *ctxt, gva_t addr, unsigned int flags); =20 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 32563a91fba9..bd69934cafd3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5843,6 +5843,12 @@ static gva_t emulator_get_untagged_addr(struct x86_e= mulate_ctxt *ctxt, addr, flags); } =20 +static bool emulator_is_lass_violation(struct x86_emulate_ctxt *ctxt, gva_= t addr, + unsigned int size, unsigned int flags) +{ + return kvm_x86_call(is_lass_violation)(emul_to_vcpu(ctxt), addr, size, fl= ags); +} + static bool emulator_is_canonical_addr(struct x86_emulate_ctxt *ctxt, gva_t addr, unsigned int flags) { @@ -5902,6 +5908,7 @@ static const struct x86_emulate_ops emulate_ops =3D { .get_xcr =3D emulator_get_xcr, .set_xcr =3D emulator_set_xcr, .get_untagged_addr =3D emulator_get_untagged_addr, + .is_lass_violation =3D emulator_is_lass_violation, .is_canonical_addr =3D emulator_is_canonical_addr, .page_address_valid =3D emulator_page_address_valid, }; --=20 2.43.0 From nobody Fri Oct 23 03:30:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9C9D4568FD0; Thu, 15 Oct 2026 20:22:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095726; cv=none; b=Jl9qWwxRRlc2J9c6al71RX5qN0eslRCu0izH6ysA4qaoNKGmav3//mbIfHCfTlaHBw7bHc9Mn9jb7XbYajWPjqQiSB38MBeL4xc9codNrrXC4HceSIe+Vekj9m+Aq+y+f3yZAMazYovCJ/KkWJ6DHEyiKI2YMO8lMAR4Oe8k+Hw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095726; c=relaxed/simple; bh=eNdj0uX51MbU2L3x9jNeMs6RwuRvHajgZdoHIqaod80=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=unNAsZzMErv3ZexVEvWAqtCATrHZJVgEef1xqDrk5Kn2rTquce9SUiy/usnCY29fVNPCIa/guyomh/z8F7FRfGsE03qcrEP0M6AHlr+oUypCxzvLF5Afyi3UeUEWF9hcgX6np9H7sCkKwTNWe9vhLK682gPqhbFMrzSYUCK39Wk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=jU6LdA9X; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="jU6LdA9X" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1792095724; x=1823631724; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eNdj0uX51MbU2L3x9jNeMs6RwuRvHajgZdoHIqaod80=; b=jU6LdA9XXbMtPE3cNH6WTRJFJO0SpvjqW5jYIspWQIX916cKso9oG3Ki 3Iak+Sw+heQgqrziKaRClKo8zVxH4erLeUHSfB7xC5O/ebapLIzujYbxE WFeH2eEacIs1KE/yYouCI9mSadhBpyY9yKaHVOE2vqUdk7eort2buJ5Iv S6poB8+kXM6MeJKnfpLZl8HJgHaNgSIydHMsoGfcvBsu+dQsPc4nDlQRw fGbP85DTb2KepToY641N6VJP8Gq3zOC7SzHclbUMZ+aeWP5umu/G6+Le0 EJKCRL4oQNZJJszqdyHrtQJjMk1b3kU/JE1k4LQZmd+vVoDJwSpl76tiz Q==; X-CSE-ConnectionGUID: UmFHVc7dSn2Ne80wMjkMMQ== X-CSE-MsgGUID: +ceUYm7/SEevwSPHIMYC6A== X-IronPort-AV: E=McAfee;i="6800,10657,11936"; a="911116" X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="911116" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Oct 2026 13:22:00 -0700 X-CSE-ConnectionGUID: dUvUQLmGSNuSDKmo35DXJQ== X-CSE-MsgGUID: bipvbnenT6uGLVA+JBvrAQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="1844441" Received: from sohilmeh.sc.intel.com ([172.25.103.65]) by fmviesa003.fm.intel.com with ESMTP; 15 Oct 2026 13:21:59 -0700 From: Sohil Mehta To: kvm@vger.kernel.org, x86@kernel.org Cc: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Shuah Khan , Binbin Wu , Peter Zijlstra , "Chang S . Bae" , Kai Huang , Fuad Tabba , Chao Gao , Yosry Ahmed , Claudio Imbrenda , David Matlack , Bala-Vignesh-Reddy , Kishen Maloor , Rick Edgecombe , Farrah Chen , Sohil Mehta , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v5 4/6] KVM: VMX: Implement LASS violation check Date: Thu, 15 Oct 2026 13:19:38 -0700 Message-ID: <20261015201940.1655956-5-sohil.mehta@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261015201940.1655956-1-sohil.mehta@intel.com> References: <20261015201940.1655956-1-sohil.mehta@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zeng Guang Add a VMX implementation of the is_lass_violation() hook to let KVM detect Linear Address Space Separation (LASS) violations on linear addresses generated during emulation. LASS uses bit 63 of the linear address to determine which half of the address space is being targeted, and reports a violation when that half doesn't match the current privilege level. Note, LASS takes effect only in IA-32e mode; it is ignored in legacy mode. LASS enforcement for supervisor-mode data accesses additionally requires SMAP to be enabled, and is suppressed for explicit accesses when RFLAGS.AC=3D1. Enforce LASS violations on emulated instruction fetches and data accesses, including implicit supervisor accesses, so that the mode-based protections are applied before paging. Also enforce LASS on the linear addresses consumed by emulated VMX and SGX ENCLS instructions. Linear addresses used for TLB invalidation (INVLPG, INVPCID, and INVVPID) and branch targets are not subject to LASS enforcement. Signed-off-by: Zeng Guang Signed-off-by: Sohil Mehta Tested-by: Kishen Maloor Tested-by: Farrah Chen Reviewed-by: Binbin Wu Reviewed-by: Chang S. Bae --- v5: - Added a function comment describing the basic flow - Replaced Binbin's SoB with a Reviewed-by - Picked up review and test tags v4: - Switch to using gva_t for the address argument - Split patch diff and reworded the commit message Note, Sashiko flagged a missing CR4.SMEP check for supervisor fetches and suggested is_64_bit_mode() instead of is_long_mode(). Both are false positives. LASS enforces the equivalent of SMEP regardless of CR4.SMEP, and it applies throughout IA-32e mode, including compatibility mode. --- arch/x86/kvm/vmx/main.c | 1 + arch/x86/kvm/vmx/nested.c | 11 ++++--- arch/x86/kvm/vmx/sgx.c | 3 +- arch/x86/kvm/vmx/vmx.c | 64 +++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/vmx.h | 3 ++ arch/x86/kvm/x86.c | 2 +- 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index d75170a6199e..0696ba3b77fe 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -1144,6 +1144,7 @@ struct kvm_x86_ops vt_x86_ops __initdata =3D { .vcpu_deliver_sipi_vector =3D kvm_vcpu_deliver_sipi_vector, =20 .get_untagged_addr =3D vmx_get_untagged_addr, + .is_lass_violation =3D vmx_is_lass_violation, =20 .mem_enc_ioctl =3D vt_op_tdx_only(mem_enc_ioctl), .vcpu_mem_enc_ioctl =3D vt_op_tdx_only(vcpu_mem_enc_ioctl), diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 9b0bfa2f854c..1794f25e0724 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5309,11 +5309,12 @@ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsi= gned long exit_qualification, *ret =3D off; =20 *ret =3D vmx_get_untagged_addr(vcpu, *ret, 0); - /* Long mode: #GP(0)/#SS(0) if the memory address is in a - * non-canonical form. This is the only check on the memory - * destination for long mode! + /* + * Long mode: #GP(0)/#SS(0) if the memory address is in a + * non-canonical form, or if the access violates LASS. */ - exn =3D is_noncanonical_address(*ret, vcpu, 0); + exn =3D is_noncanonical_address(*ret, vcpu, 0) || + vmx_is_lass_violation(vcpu, *ret, len, 0); } else { /* * When not in long mode, the virtual/linear address is @@ -6128,7 +6129,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) if (type !=3D VMX_VPID_EXTENT_ALL_CONTEXT && !operand.vpid) return nested_vmx_fail(vcpu, VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); =20 - /* LAM doesn't apply to addresses that are inputs to TLB invalidation. */ + /* LAM and LASS don't apply to addresses that are inputs to TLB invalidat= ion. */ if (type =3D=3D VMX_VPID_EXTENT_INDIVIDUAL_ADDR && is_noncanonical_invlpg_address(operand.gla, vcpu)) return nested_vmx_fail(vcpu, VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); diff --git a/arch/x86/kvm/vmx/sgx.c b/arch/x86/kvm/vmx/sgx.c index 771c75a58343..4ac305ed6dea 100644 --- a/arch/x86/kvm/vmx/sgx.c +++ b/arch/x86/kvm/vmx/sgx.c @@ -39,7 +39,8 @@ static int sgx_get_encls_gva(struct kvm_vcpu *vcpu, unsig= ned long offset, fault =3D true; } else if (likely(is_64_bit_mode(vcpu))) { *gva =3D vmx_get_untagged_addr(vcpu, *gva, 0); - fault =3D is_noncanonical_address(*gva, vcpu, 0); + fault =3D is_noncanonical_address(*gva, vcpu, 0) || + vmx_is_lass_violation(vcpu, *gva, size, 0); } else { *gva &=3D 0xffffffff; fault =3D (s.unusable) || diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 04a9acf4a39a..6245de123ec3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8469,6 +8469,70 @@ gva_t vmx_get_untagged_addr(struct kvm_vcpu *vcpu, g= va_t gva, unsigned int flags return (sign_extend64(gva, lam_bit) & ~BIT_ULL(63)) | (gva & BIT_ULL(63)); } =20 +/* + * Check if an access violates LASS purely based on bit 63 of the linear + * address and whether the access targets the "wrong" half of the address + * space. The basic flow is straightforward: + * + * if (exempt from LASS) + * no violation; + * else if (user access) + * violation when address is in the supervisor half; + * else + * violation when address is in the user half; + * + * but the actual behavior is far more subtle due to the many exceptions a= nd + * edge cases. For example, the implementation depends on which accesses a= re + * exempt, what constitutes a user access, and how supervisor data accesses + * differ from instruction fetches. + */ +bool vmx_is_lass_violation(struct kvm_vcpu *vcpu, gva_t gva, + unsigned int size, unsigned int flags) +{ + const bool is_supervisor_address =3D !!(gva & BIT_ULL(63)); + const bool implicit_supervisor =3D !!(flags & X86EMUL_F_IMPLICIT); + const bool fetch =3D !!(flags & X86EMUL_F_FETCH); + + if (!kvm_is_cr4_bit_set(vcpu, X86_CR4_LASS) || !is_long_mode(vcpu)) + return false; + + /* + * INVLPG isn't subject to LASS, e.g. to allow invalidating userspace + * addresses without toggling RFLAGS.AC. Branch targets aren't + * subject to LASS in order to simplify far control transfers (the + * subsequent fetch will enforce LASS as appropriate). + */ + if (flags & (X86EMUL_F_BRANCH | X86EMUL_F_INVLPG)) + return false; + + if (!implicit_supervisor && vmx_get_cpl(vcpu) =3D=3D 3) + return is_supervisor_address; + + /* + * LASS enforcement for supervisor-mode data accesses depends on SMAP + * being enabled, and like SMAP ignores explicit accesses if RFLAGS.AC=3D= 1. + */ + if (!fetch) { + if (!kvm_is_cr4_bit_set(vcpu, X86_CR4_SMAP)) + return false; + + if (!implicit_supervisor && (kvm_get_rflags(vcpu) & X86_EFLAGS_AC)) + return false; + } + + /* + * The entire access must be in the appropriate address space. Note, + * if LAM is supported, @gva has already been untagged, so barring a + * massive architecture change to expand the canonical address range, + * it's impossible for a user access to straddle user and supervisor + * address spaces. + */ + if (size && !((gva + size - 1) & BIT_ULL(63))) + return true; + + return !is_supervisor_address; +} + static unsigned int vmx_handle_intel_pt_intr(void) { struct kvm_vcpu *vcpu =3D kvm_get_running_vcpu(); diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 6c9dd5b2365d..48ae3b213f97 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -353,6 +353,9 @@ u64 vmx_get_l2_tsc_multiplier(struct kvm_vcpu *vcpu); =20 gva_t vmx_get_untagged_addr(struct kvm_vcpu *vcpu, gva_t gva, unsigned int= flags); =20 +bool vmx_is_lass_violation(struct kvm_vcpu *vcpu, gva_t gva, + unsigned int size, unsigned int flags); + void vmx_update_cpu_dirty_logging(struct kvm_vcpu *vcpu, bool enable); =20 u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bd69934cafd3..ba94ade695fc 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10857,7 +10857,7 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsig= ned long type, gva_t gva) switch (type) { case INVPCID_TYPE_INDIV_ADDR: /* - * LAM doesn't apply to addresses that are inputs to TLB + * LAM and LASS don't apply to addresses that are inputs to TLB * invalidation. */ if ((!pcid_enabled && (operand.pcid !=3D 0)) || --=20 2.43.0 From nobody Fri Oct 23 03:30:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9BB0955C1CC; Thu, 15 Oct 2026 20:22:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095727; cv=none; b=AiSfn0WFHP+RYcSL4YeD1LLcoQl22Sskoj1h4jSmhZ4LZOgZDAAtmZikkhlQSnDCWq4ocgNldYZhvyQ/vWcz0KN1vOb40VoJnR4aeQZrvgi0hDlT4RTQ+2gOGQ1tkLwhEmHcbyAkSQZvZRbAUZ9w2B1rmlW8MFWXBrYVsfJCF/o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095727; c=relaxed/simple; bh=FYLCcnpyCZgCtke9hcMbRzLqqcNwkQcjacFto8RrTKo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Dig4B8psMK7JmJ85CWDwJ/kqify5X9ILi6UVw7DtsGy81Q5yCJh6SmM+w5UiYIZJBkAD9FgGQOuoN8SE2/eZ2q2iNeBuWfh88qzm7gRqsdajRF90cOtyho8xkcn4wTP0L3jMPxkbG1rBaGegd5Xy3oQSrnz58XEkxsXmxh291y8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=IKm7IlRX; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="IKm7IlRX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1792095724; x=1823631724; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FYLCcnpyCZgCtke9hcMbRzLqqcNwkQcjacFto8RrTKo=; b=IKm7IlRXKsHO94yhF8I5KEFhiN+EQXn5A70N6qgEwl+7E31hyNXNyDJH 4+QOppyv/j+lZc2C9+sias1iRSrNFhkZE7+gaqdDxDGbA4369j0XqMO54 N6d7Cs+P45E6ucuy1ahqTvOU3Nt6TIi+6sGUFBhQAj06vNt3PZij6Ljrp ICAW5ouSqSR64DmsPmN9Nbx480QJR91p0tdbTZM6jdGeISCGPVM/GhWgQ D7w7AQtMZqZbr8vP2HMLcLet1bPljeXpmNqtfegD7CdUWDDSVrnYaIN/a 4w8glQb0C7oilt5yF1k4Vv5DLJx6JwdwECj5Rx9elha0W4OYs3zPbkBRb A==; X-CSE-ConnectionGUID: oLTbJpQ9TLSpBMWMzyfPKw== X-CSE-MsgGUID: eMJ2hVaET+uqz8AEgD4PeQ== X-IronPort-AV: E=McAfee;i="6800,10657,11936"; a="911128" X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="911128" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Oct 2026 13:22:01 -0700 X-CSE-ConnectionGUID: ugIUIcZeTDu5BQZXE1elJA== X-CSE-MsgGUID: 3OG4PUg7Q32MwJKFWRBpMg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="1844495" Received: from sohilmeh.sc.intel.com ([172.25.103.65]) by fmviesa003.fm.intel.com with ESMTP; 15 Oct 2026 13:21:59 -0700 From: Sohil Mehta To: kvm@vger.kernel.org, x86@kernel.org Cc: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Shuah Khan , Binbin Wu , Peter Zijlstra , "Chang S . Bae" , Kai Huang , Fuad Tabba , Chao Gao , Yosry Ahmed , Claudio Imbrenda , David Matlack , Bala-Vignesh-Reddy , Kishen Maloor , Rick Edgecombe , Farrah Chen , Sohil Mehta , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v5 5/6] KVM: x86: Virtualize LASS and advertise support to userspace Date: Thu, 15 Oct 2026 13:19:39 -0700 Message-ID: <20261015201940.1655956-6-sohil.mehta@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261015201940.1655956-1-sohil.mehta@intel.com> References: <20261015201940.1655956-1-sohil.mehta@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zeng Guang Virtualize Linear Address Space Separation (LASS) by letting the guest enable CR4.LASS[bit 27]. Allow the guest to set CR4.LASS only if LASS is enumerated in the guest's CPUID. Set CR4.LASS in the emulated IA32_VMX_CR4_FIXED1 MSR so that LASS can be enabled in nested VMX operation as well. Keep CR4.LASS KVM-owned instead of making it guest-owned. LASS is expected to be enabled once per vCPU at boot and rarely toggled at runtime. LASS is enumerated by CPUID.(EAX=3D07H,ECX=3D1):EAX.LASS[bit 6] and only works in IA-32e mode. Advertise LASS to userspace on 64-bit kernels and only when it is supported by the host. Notably, it will not be exposed to userspace if the deprecated vsyscall=3Demulate is set on the kernel command line. Signed-off-by: Zeng Guang Signed-off-by: Sohil Mehta Tested-by: Kishen Maloor Tested-by: Farrah Chen Reviewed-by: Binbin Wu --- v5: - Replaced Binbin's SoB with a Reviewed-by - Picked up Tested-by tags v4: - Split patch diffs and reworded the commit message - Use X86_64_F() instead of F() --- arch/x86/kvm/cpuid.c | 1 + arch/x86/kvm/regs.h | 4 +++- arch/x86/kvm/vmx/vmx.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index adafd6fa2c54..3941f5ce9425 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -1016,6 +1016,7 @@ void kvm_initialize_cpu_caps(void) F(SM4), F(AVX_VNNI), F(AVX512_BF16), + X86_64_F(LASS), F(CMPCCXADD), F(FZRM), F(FSRS), diff --git a/arch/x86/kvm/regs.h b/arch/x86/kvm/regs.h index 97c17b120a57..a1ac69ac20f5 100644 --- a/arch/x86/kvm/regs.h +++ b/arch/x86/kvm/regs.h @@ -28,7 +28,7 @@ static_assert(!(KVM_POSSIBLE_CR0_GUEST_BITS & X86_CR0_PDP= TR_BITS)); | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_VMXE \ | X86_CR4_SMAP | X86_CR4_PKE | X86_CR4_UMIP \ - | X86_CR4_LAM_SUP | X86_CR4_CET)) + | X86_CR4_LAM_SUP | X86_CR4_CET | X86_CR4_LASS)) =20 #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) =20 @@ -404,6 +404,8 @@ static inline bool __kvm_is_valid_cr4(struct kvm_vcpu *= vcpu, unsigned long cr4) __reserved_bits |=3D X86_CR4_PCIDE; \ if (!__cpu_has(__c, X86_FEATURE_LAM)) \ __reserved_bits |=3D X86_CR4_LAM_SUP; \ + if (!__cpu_has(__c, X86_FEATURE_LASS)) \ + __reserved_bits |=3D X86_CR4_LASS; \ if (!__cpu_has(__c, X86_FEATURE_SHSTK) && \ !__cpu_has(__c, X86_FEATURE_IBT)) \ __reserved_bits |=3D X86_CR4_CET; \ diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6245de123ec3..273c09f15fa3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7751,6 +7751,7 @@ static void nested_vmx_cr_fixed1_bits_update(struct k= vm_vcpu *vcpu) =20 entry =3D kvm_find_cpuid_entry_index(vcpu, 0x7, 1); cr4_fixed1_update(X86_CR4_LAM_SUP, eax, feature_bit(LAM)); + cr4_fixed1_update(X86_CR4_LASS, eax, feature_bit(LASS)); =20 #undef cr4_fixed1_update } --=20 2.43.0 From nobody Fri Oct 23 03:30:48 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 898A553CA6D; Thu, 15 Oct 2026 20:22:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095729; cv=none; b=JNj9apMgv2cGMyM13wBCF/hPLtJDx+SHKf0HEYJkUMe9Iezc1Pv3kahSO54s6KiRwPSx1qA7xc9H0EIxeGZ9SJhs9IvyErugdE+xOB7o/7ZBm5y0DRNHtuCPMGABF5b49yWpY6/OGMaW5x4sjcNVrPc7j9UH/6aODj18uL6n+jI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792095729; c=relaxed/simple; bh=bE5+1IemOECT05OEvh34mnl/ZoqjgtYYKl4gXF9D0BA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jjLM9TEjlqhwLHDANUl6HMY3H5OmRBHGewc1ldOlzgUW1taxIHs5lBFXigaztWuMY79oO9hOcB9MIzKrSLmVeMi6z461z4i/9vJSkIZDy2yqZ3AGpAiYSXNB50HGGhN2FPN146PUCnghlXG4SH0AL+2YfUtZglT3ca/wgTijMrs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=HDwgL3bg; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="HDwgL3bg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1792095726; x=1823631726; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bE5+1IemOECT05OEvh34mnl/ZoqjgtYYKl4gXF9D0BA=; b=HDwgL3bgrUZ1ZvZ5eiV1WNWWMjhbCtKpILnDt1VTOTOEHW7SbSdNiPOS sw1W+SrzeS8LH6ZKb53dBOoyFh7YkxT22MzuWhpi54bmIRJQH1GgVIEK9 LIoPD+m1//qvauX/mkmT/CFzFj6xc9b38QVlv9A1W1JwPLmMEZ6kQxDMU CzEwIOvWZYVEjEy+s8L+3PQ0kxYL1W+IrS70UVVeWYmO1dHHVgqchO4gt sfnlJz3di33uJxW1YWARvG/01B9CCWn4gQCQFehoU3Vk/vXQGxZcnCZ3W A+GH4W+lDCzRF5kYhb780ejqNNVriwo7curUYpozjcFSmr5/5rqg+3lQi A==; X-CSE-ConnectionGUID: 4/JoFbNAQre+4ugryk9NQQ== X-CSE-MsgGUID: 7HjycFQ0S96cj5PRCKzmSg== X-IronPort-AV: E=McAfee;i="6800,10657,11936"; a="911138" X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="911138" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Oct 2026 13:22:02 -0700 X-CSE-ConnectionGUID: REvyi5jzSzS0k4n65gpYaQ== X-CSE-MsgGUID: fTOr0R0jRGOlhEPoB7vVEg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,160,1787036400"; d="scan'208";a="1844502" Received: from sohilmeh.sc.intel.com ([172.25.103.65]) by fmviesa003.fm.intel.com with ESMTP; 15 Oct 2026 13:22:00 -0700 From: Sohil Mehta To: kvm@vger.kernel.org, x86@kernel.org Cc: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Shuah Khan , Binbin Wu , Peter Zijlstra , "Chang S . Bae" , Kai Huang , Fuad Tabba , Chao Gao , Yosry Ahmed , Claudio Imbrenda , David Matlack , Bala-Vignesh-Reddy , Kishen Maloor , Rick Edgecombe , Farrah Chen , Sohil Mehta , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v5 6/6] KVM: selftests: Extend set_sregs_test to cover LASS Date: Thu, 15 Oct 2026 13:19:40 -0700 Message-ID: <20261015201940.1655956-7-sohil.mehta@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261015201940.1655956-1-sohil.mehta@intel.com> References: <20261015201940.1655956-1-sohil.mehta@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend set_sregs_test to cover CR4.LASS and verify that KVM_SET_SREGS accepts CR4.LASS when LASS is supported, and rejects it, without modifying sregs, when it isn't. Signed-off-by: Sohil Mehta Tested-by: Kishen Maloor Tested-by: Farrah Chen Reviewed-by: Binbin Wu --- v5: - Avoided the CR4 write test specific to LASS. - Picked up review and test tags v4: - New patch --- tools/testing/selftests/kvm/include/x86/processor.h | 2 ++ tools/testing/selftests/kvm/x86/set_sregs_test.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 5898a277a2e0..606ee9fe0ddb 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -81,6 +81,7 @@ const char *ex_str(int vector); #define X86_CR4_SMEP (1ul << 20) #define X86_CR4_SMAP (1ul << 21) #define X86_CR4_PKE (1ul << 22) +#define X86_CR4_LASS (1ul << 27) =20 struct xstate_header { u64 xstate_bv; @@ -197,6 +198,7 @@ struct kvm_x86_cpu_feature { #define X86_FEATURE_SPEC_CTRL KVM_X86_CPU_FEATURE(0x7, 0, EDX, 26) #define X86_FEATURE_ARCH_CAPABILITIES KVM_X86_CPU_FEATURE(0x7, 0, EDX, 29) #define X86_FEATURE_PKS KVM_X86_CPU_FEATURE(0x7, 0, ECX, 31) +#define X86_FEATURE_LASS KVM_X86_CPU_FEATURE(0x7, 1, EAX, 6) #define X86_FEATURE_XTILECFG KVM_X86_CPU_FEATURE(0xD, 0, EAX, 17) #define X86_FEATURE_XTILEDATA KVM_X86_CPU_FEATURE(0xD, 0, EAX, 18) #define X86_FEATURE_XSAVES KVM_X86_CPU_FEATURE(0xD, 1, EAX, 3) diff --git a/tools/testing/selftests/kvm/x86/set_sregs_test.c b/tools/testi= ng/selftests/kvm/x86/set_sregs_test.c index 5afc4187f5eb..f30dc61fe00f 100644 --- a/tools/testing/selftests/kvm/x86/set_sregs_test.c +++ b/tools/testing/selftests/kvm/x86/set_sregs_test.c @@ -72,6 +72,8 @@ static u64 calc_supported_cr4_feature_bits(void) cr4 |=3D X86_CR4_SMAP; if (kvm_cpu_has(X86_FEATURE_PKU)) cr4 |=3D X86_CR4_PKE; + if (kvm_cpu_has(X86_FEATURE_LASS)) + cr4 |=3D X86_CR4_LASS; =20 return cr4; } @@ -128,6 +130,7 @@ static void test_cr_bits(struct kvm_vcpu *vcpu, u64 cr4) TEST_INVALID_SREG_BIT(vcpu, cr4, sregs, X86_CR4_SMEP); TEST_INVALID_SREG_BIT(vcpu, cr4, sregs, X86_CR4_SMAP); TEST_INVALID_SREG_BIT(vcpu, cr4, sregs, X86_CR4_PKE); + TEST_INVALID_SREG_BIT(vcpu, cr4, sregs, X86_CR4_LASS); =20 for (i =3D 32; i < 64; i++) TEST_INVALID_SREG_BIT(vcpu, cr0, sregs, BIT(i)); --=20 2.43.0