All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: VMX: Add array_index_nospec() to evmcs_field_offset()
@ 2026-10-17  9:30 Amirmohammad Eftekhar
  2026-10-26  9:00 ` Vitaly Kuznetsov
  0 siblings, 1 reply; 4+ messages in thread
From: Amirmohammad Eftekhar @ 2026-10-17  9:30 UTC (permalink / raw)
  To: seanjc, pbonzini; +Cc: kvm, linux-kernel

evmcs_field_offset() bounds-checks the guest-supplied field index against
nr_evmcs_1_fields and then indexes vmcs_field_to_evmcs_1[] without an
array_index_nospec() clamp, unlike its vmcs12 counterpart
get_vmcs12_field_offset().  An enlightened VMREAD/VMWRITE from the guest
can therefore speculatively read out of bounds of vmcs_field_to_evmcs_1[]
past the bound check (Spectre v1).

Clamp the index with array_index_nospec(), mirroring
get_vmcs12_field_offset().

Signed-off-by: Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de>
---
 arch/x86/kvm/vmx/hyperv_evmcs.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/kvm/vmx/hyperv_evmcs.h b/arch/x86/kvm/vmx/hyperv_evmcs.h
index bc08fe405..052b62b8e 100644
--- a/arch/x86/kvm/vmx/hyperv_evmcs.h
+++ b/arch/x86/kvm/vmx/hyperv_evmcs.h
@@ -136,6 +136,8 @@ static __always_inline int evmcs_field_offset(unsigned long field,
 	if (unlikely(index >= nr_evmcs_1_fields))
 		return -ENOENT;
 
+	index = array_index_nospec(index, nr_evmcs_1_fields);
+
 	evmcs_field = &vmcs_field_to_evmcs_1[index];
 
 	/*
-- 
2.54.0 (Apple Git-157)


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH] KVM: VMX: Add array_index_nospec() to evmcs_field_offset()
@ 2026-10-23 17:13 Amirmohammad Eftekhar
  2026-10-24  1:17 ` Sean Christopherson
  0 siblings, 1 reply; 4+ messages in thread
From: Amirmohammad Eftekhar @ 2026-10-23 17:13 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: Vitaly Kuznetsov, kvm, linux-kernel, amirmohammad.eftekhar

From: Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de>

evmcs_field_offset() bounds-checks the guest-supplied field index against
nr_evmcs_1_fields and then indexes vmcs_field_to_evmcs_1[] with it, but,
unlike its vmcs12 counterpart get_vmcs12_field_offset(), it does not clamp
the index with array_index_nospec() after the check.  The field index is
derived from a guest-supplied VMCS field encoding on the enlightened
VMREAD/VMWRITE path, so the array access can be performed speculatively
past the bounds check (Spectre v1), disclosing memory adjacent to
vmcs_field_to_evmcs_1[].

Clamp the index with array_index_nospec() immediately after the bounds
check, mirroring get_vmcs12_field_offset().

Signed-off-by: Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de>
---
 arch/x86/kvm/vmx/hyperv_evmcs.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/kvm/vmx/hyperv_evmcs.h b/arch/x86/kvm/vmx/hyperv_evmcs.h
index bc08fe40590e..052b62b8ed8e 100644
--- a/arch/x86/kvm/vmx/hyperv_evmcs.h
+++ b/arch/x86/kvm/vmx/hyperv_evmcs.h
@@ -136,6 +136,8 @@ static __always_inline int evmcs_field_offset(unsigned long field,
 	if (unlikely(index >= nr_evmcs_1_fields))
 		return -ENOENT;
 
+	index = array_index_nospec(index, nr_evmcs_1_fields);
+
 	evmcs_field = &vmcs_field_to_evmcs_1[index];
 
 	/*
-- 
2.43.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: VMX: Add array_index_nospec() to evmcs_field_offset()
  2026-10-23 17:13 [PATCH] KVM: VMX: Add array_index_nospec() to evmcs_field_offset() Amirmohammad Eftekhar
@ 2026-10-24  1:17 ` Sean Christopherson
  0 siblings, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-10-24  1:17 UTC (permalink / raw)
  To: Amirmohammad Eftekhar; +Cc: Paolo Bonzini, Vitaly Kuznetsov, kvm, linux-kernel

On Fri, Oct 23, 2026, Amirmohammad Eftekhar wrote:
> From: Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de>
> 
> evmcs_field_offset() bounds-checks the guest-supplied field index against
> nr_evmcs_1_fields and then indexes vmcs_field_to_evmcs_1[] with it, but,
> unlike its vmcs12 counterpart get_vmcs12_field_offset(), it does not clamp
> the index with array_index_nospec() after the check.  The field index is
> derived from a guest-supplied VMCS field encoding on the enlightened
> VMREAD/VMWRITE path, so the array access can be performed speculatively
> past the bounds check (Spectre v1), disclosing memory adjacent to
> vmcs_field_to_evmcs_1[].
> 
> Clamp the index with array_index_nospec() immediately after the bounds
> check, mirroring get_vmcs12_field_offset().
> 
> Signed-off-by: Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de>
> ---

You already posted this exact patch[*], and at a glance several of the bug reports
appear to be duplicates as well.  Please stop spamming duplicates.  If you have
questions about the flow and/or timing of patches, e.g. since we're in a merge
window, then Documentation/process/maintainer-kvm-x86.rst is your friend.

[*] https://lore.kernel.org/all/20261017093016.32348-3-amirmohammad.eftekhar@cispa.de

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: VMX: Add array_index_nospec() to evmcs_field_offset()
  2026-10-17  9:30 Amirmohammad Eftekhar
@ 2026-10-26  9:00 ` Vitaly Kuznetsov
  0 siblings, 0 replies; 4+ messages in thread
From: Vitaly Kuznetsov @ 2026-10-26  9:00 UTC (permalink / raw)
  To: Amirmohammad Eftekhar; +Cc: kvm, linux-kernel, seanjc, pbonzini

Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de> writes:

> evmcs_field_offset() bounds-checks the guest-supplied field index against
> nr_evmcs_1_fields and then indexes vmcs_field_to_evmcs_1[] without an
> array_index_nospec() clamp, unlike its vmcs12 counterpart
> get_vmcs12_field_offset().  An enlightened VMREAD/VMWRITE from the guest
> can therefore speculatively read out of bounds of vmcs_field_to_evmcs_1[]
> past the bound check (Spectre v1).

I think your concern is valid but the changelog requires massaging.

"enlightened VMREAD/VMWRITE" is basically the guest doing just memory
read/write and we can't do much about it. These reads/writes don't trap
to KVM. What the guest can actually do, is try executing 'normal'
VMREAD/VMWRITE instructions.

Note, Hyper-V TLFS states that

"Any VMREAD or VMWRITE instructions while an enlightened VMCS is active
is unsupported and can result in unexpected behavior."

and our initial implementation was completely forbidding
both. Unfortunately, it turned out that Windows itself does not comply
and does occasional VMREADs, see 6cbbaab60ff3 ("KVM: nVMX: Allow VMREAD
when Enlightened VMCS is in use"). I think you need to add corresponding
Fixes: tag.

My understanding is that VMWRITEs are still completely forbidden while
eVMCS is active. So I think you need to say something like

"""
Regular VMREAD instruction is allowed when eVMCS is active since
6cbbaab60ff3 ("KVM: nVMX: Allow VMREAD when Enlightened VMCS is in use")
but unlike get_vmcs12_field_offset() evmcs_field_offset() does not clamp
the index and thus the guest may be able to speculatively access
hypervisor's memory.
"""
Note, 'offset' is short and thus the exposure is somewhat limited.

Other pathes using evmcs_field_offset() should not be under the direct
guest control but array_index_nospec() should not hurt.

>
> Clamp the index with array_index_nospec(), mirroring
> get_vmcs12_field_offset().
>
> Signed-off-by: Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de>
> ---
>  arch/x86/kvm/vmx/hyperv_evmcs.h | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/x86/kvm/vmx/hyperv_evmcs.h b/arch/x86/kvm/vmx/hyperv_evmcs.h
> index bc08fe405..052b62b8e 100644
> --- a/arch/x86/kvm/vmx/hyperv_evmcs.h
> +++ b/arch/x86/kvm/vmx/hyperv_evmcs.h
> @@ -136,6 +136,8 @@ static __always_inline int evmcs_field_offset(unsigned long field,
>  	if (unlikely(index >= nr_evmcs_1_fields))
>  		return -ENOENT;
>  
> +	index = array_index_nospec(index, nr_evmcs_1_fields);
> +
>  	evmcs_field = &vmcs_field_to_evmcs_1[index];
>  
>  	/*

-- 
Vitaly


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-26  9:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23 17:13 [PATCH] KVM: VMX: Add array_index_nospec() to evmcs_field_offset() Amirmohammad Eftekhar
2026-10-24  1:17 ` Sean Christopherson
  -- strict thread matches above, loose matches on Subject: below --
2026-10-17  9:30 Amirmohammad Eftekhar
2026-10-26  9:00 ` Vitaly Kuznetsov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.