Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: Sohil Mehta <sohil.mehta@intel.com>
To: kvm@vger.kernel.org, x86@kernel.org
Cc: Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
	Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"H . Peter Anvin" <hpa@zytor.com>, Shuah Khan <shuah@kernel.org>,
	Binbin Wu <binbin.wu@linux.intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	"Chang S . Bae" <chang.seok.bae@intel.com>,
	Kai Huang <kai.huang@intel.com>,
	Fuad Tabba <fuad.tabba@linux.dev>, Chao Gao <chao.gao@intel.com>,
	Yosry Ahmed <yosry@kernel.org>,
	Claudio Imbrenda <imbrenda@linux.ibm.com>,
	David Matlack <dmatlack@google.com>,
	Bala-Vignesh-Reddy <reddybalavignesh9979@gmail.com>,
	Kishen Maloor <kishen.maloor@intel.com>,
	Rick Edgecombe <rick.p.edgecombe@intel.com>,
	Sohil Mehta <sohil.mehta@intel.com>,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [PATCH v4 3/7] KVM: x86: Add LASS violation checks during instruction emulation
Date: Wed,  5 Aug 2026 18:15:32 -0700	[thread overview]
Message-ID: <20260806011536.4172258-4-sohil.mehta@intel.com> (raw)
In-Reply-To: <20260806011536.4172258-1-sohil.mehta@intel.com>

From: Zeng Guang <guang.zeng@intel.com>

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 <guang.zeng@intel.com>
Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com>
Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
---
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 warns 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 e213c9ae3e30..a82b20281f31 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -146,6 +146,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_host.h
index 283847619ff8..d2181a805ace 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1727,6 +1727,8 @@ struct kvm_x86_ops {
 	unsigned long (*vcpu_get_apicv_inhibit_reasons)(struct kvm_vcpu *vcpu);
 
 	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 7f04544cfee5..9cbfde649064 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -693,6 +693,16 @@ static __always_inline int __linearize(struct x86_emulate_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
+	 * alignment-check faults, so any order is legal.
+	 */
+	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;
@@ -799,6 +809,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, true);
 }
 
@@ -806,6 +819,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, true);
 }
 
diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
index 97421b8dde13..f136d3d0ba42 100644
--- a/arch/x86/kvm/kvm_emulate.h
+++ b/arch/x86/kvm/kvm_emulate.h
@@ -249,7 +249,8 @@ struct x86_emulate_ops {
 
 	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);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d94b59140c45..70c8439312c3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5800,6 +5800,12 @@ static gva_t emulator_get_untagged_addr(struct x86_emulate_ctxt *ctxt,
 					       addr, flags);
 }
 
+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, flags);
+}
+
 static bool emulator_is_canonical_addr(struct x86_emulate_ctxt *ctxt,
 				       gva_t addr, unsigned int flags)
 {
@@ -5859,6 +5865,7 @@ static const struct x86_emulate_ops emulate_ops = {
 	.get_xcr             = emulator_get_xcr,
 	.set_xcr             = emulator_set_xcr,
 	.get_untagged_addr   = emulator_get_untagged_addr,
+	.is_lass_violation   = emulator_is_lass_violation,
 	.is_canonical_addr   = emulator_is_canonical_addr,
 	.page_address_valid  = emulator_page_address_valid,
 };
-- 
2.43.0


  parent reply	other threads:[~2026-08-06  1:18 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06  1:15 [PATCH v4 0/7] KVM: x86: Add LASS virtualization support Sohil Mehta
2026-08-06  1:15 ` [PATCH v4 1/7] KVM: x86: Add an emulator flag to differentiate branch targets from fetches Sohil Mehta
2026-08-06  1:15 ` [PATCH v4 2/7] KVM: x86: Use linear_read_system() to read the TSS I/O bitmap Sohil Mehta
2026-08-06  1:15 ` Sohil Mehta [this message]
2026-08-06  1:15 ` [PATCH v4 4/7] KVM: VMX: Implement LASS violation check Sohil Mehta
2026-08-06  1:52   ` sashiko-bot
2026-08-07  1:42     ` Sohil Mehta
2026-08-06  1:15 ` [PATCH v4 5/7] KVM: x86: Virtualize LASS and advertise support to userspace Sohil Mehta
2026-08-06  1:15 ` [PATCH v4 6/7] KVM: selftests: Add coverage for LASS CPUID and CR4 handling Sohil Mehta
2026-08-06  1:15 ` [PATCH v4 7/7] selftests/x86: Add a userspace test for LASS enforcement Sohil Mehta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260806011536.4172258-4-sohil.mehta@intel.com \
    --to=sohil.mehta@intel.com \
    --cc=binbin.wu@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=chang.seok.bae@intel.com \
    --cc=chao.gao@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dmatlack@google.com \
    --cc=fuad.tabba@linux.dev \
    --cc=hpa@zytor.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=kai.huang@intel.com \
    --cc=kishen.maloor@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=reddybalavignesh9979@gmail.com \
    --cc=rick.p.edgecombe@intel.com \
    --cc=seanjc@google.com \
    --cc=shuah@kernel.org \
    --cc=tglx@kernel.org \
    --cc=x86@kernel.org \
    --cc=yosry@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox