--- /dev/null
+From 3ee859e384d453d6ac68bfd5971f630d9fa46ad3 Mon Sep 17 00:00:00 2001
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Date: Sun, 9 Jan 2022 18:36:43 +0900
+Subject: block: Fix wrong offset in bio_truncate()
+
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+
+commit 3ee859e384d453d6ac68bfd5971f630d9fa46ad3 upstream.
+
+bio_truncate() clears the buffer outside of last block of bdev, however
+current bio_truncate() is using the wrong offset of page. So it can
+return the uninitialized data.
+
+This happened when both of truncated/corrupted FS and userspace (via
+bdev) are trying to read the last of bdev.
+
+Reported-by: syzbot+ac94ae5f68b84197f41c@syzkaller.appspotmail.com
+Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/875yqt1c9g.fsf@mail.parknet.co.jp
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/bio.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -569,7 +569,8 @@ static void bio_truncate(struct bio *bio
+ offset = new_size - done;
+ else
+ offset = 0;
+- zero_user(bv.bv_page, offset, bv.bv_len - offset);
++ zero_user(bv.bv_page, bv.bv_offset + offset,
++ bv.bv_len - offset);
+ truncated = true;
+ }
+ done += bv.bv_len;
--- /dev/null
+From 6cbbaab60ff33f59355492c241318046befd9ffc Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 12 Jan 2022 18:01:34 +0100
+Subject: KVM: nVMX: Allow VMREAD when Enlightened VMCS is in use
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+commit 6cbbaab60ff33f59355492c241318046befd9ffc upstream.
+
+Hyper-V TLFS explicitly forbids VMREAD and VMWRITE instructions when
+Enlightened VMCS interface is in use:
+
+"Any VMREAD or VMWRITE instructions while an enlightened VMCS is
+active is unsupported and can result in unexpected behavior.""
+
+Windows 11 + WSL2 seems to ignore this, attempts to VMREAD VMCS field
+0x4404 ("VM-exit interruption information") are observed. Failing
+these attempts with nested_vmx_failInvalid() makes such guests
+unbootable.
+
+Microsoft confirms this is a Hyper-V bug and claims that it'll get fixed
+eventually but for the time being we need a workaround. (Temporary) allow
+VMREAD to get data from the currently loaded Enlightened VMCS.
+
+Note: VMWRITE instructions remain forbidden, it is not clear how to
+handle them properly and hopefully won't ever be needed.
+
+Reviewed-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Message-Id: <20220112170134.1904308-6-vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx/evmcs.h | 12 ++++++++++
+ arch/x86/kvm/vmx/nested.c | 55 ++++++++++++++++++++++++++++++++--------------
+ 2 files changed, 51 insertions(+), 16 deletions(-)
+
+--- a/arch/x86/kvm/vmx/evmcs.h
++++ b/arch/x86/kvm/vmx/evmcs.h
+@@ -96,6 +96,18 @@ static __always_inline int evmcs_field_o
+ return evmcs_field->offset;
+ }
+
++static inline u64 evmcs_read_any(struct hv_enlightened_vmcs *evmcs,
++ unsigned long field, u16 offset)
++{
++ /*
++ * vmcs12_read_any() doesn't care whether the supplied structure
++ * is 'struct vmcs12' or 'struct hv_enlightened_vmcs' as it takes
++ * the exact offset of the required field, use it for convenience
++ * here.
++ */
++ return vmcs12_read_any((void *)evmcs, field, offset);
++}
++
+ #if IS_ENABLED(CONFIG_HYPERV)
+
+ static __always_inline int get_evmcs_offset(unsigned long field,
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -7,6 +7,7 @@
+ #include <asm/mmu_context.h>
+
+ #include "cpuid.h"
++#include "evmcs.h"
+ #include "hyperv.h"
+ #include "mmu.h"
+ #include "nested.h"
+@@ -5074,27 +5075,49 @@ static int handle_vmread(struct kvm_vcpu
+ if (!nested_vmx_check_permission(vcpu))
+ return 1;
+
+- /*
+- * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA,
+- * any VMREAD sets the ALU flags for VMfailInvalid.
+- */
+- if (vmx->nested.current_vmptr == INVALID_GPA ||
+- (is_guest_mode(vcpu) &&
+- get_vmcs12(vcpu)->vmcs_link_pointer == INVALID_GPA))
+- return nested_vmx_failInvalid(vcpu);
+-
+ /* Decode instruction info and find the field to read */
+ field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf));
+
+- offset = get_vmcs12_field_offset(field);
+- if (offset < 0)
+- return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
++ if (!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
++ /*
++ * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA,
++ * any VMREAD sets the ALU flags for VMfailInvalid.
++ */
++ if (vmx->nested.current_vmptr == INVALID_GPA ||
++ (is_guest_mode(vcpu) &&
++ get_vmcs12(vcpu)->vmcs_link_pointer == INVALID_GPA))
++ return nested_vmx_failInvalid(vcpu);
++
++ offset = get_vmcs12_field_offset(field);
++ if (offset < 0)
++ return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
++
++ if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field))
++ copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12);
++
++ /* Read the field, zero-extended to a u64 value */
++ value = vmcs12_read_any(vmcs12, field, offset);
++ } else {
++ /*
++ * Hyper-V TLFS (as of 6.0b) explicitly states, that while an
++ * enlightened VMCS is active VMREAD/VMWRITE instructions are
++ * unsupported. Unfortunately, certain versions of Windows 11
++ * don't comply with this requirement which is not enforced in
++ * genuine Hyper-V. Allow VMREAD from an enlightened VMCS as a
++ * workaround, as misbehaving guests will panic on VM-Fail.
++ * Note, enlightened VMCS is incompatible with shadow VMCS so
++ * all VMREADs from L2 should go to L1.
++ */
++ if (WARN_ON_ONCE(is_guest_mode(vcpu)))
++ return nested_vmx_failInvalid(vcpu);
+
+- if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field))
+- copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12);
++ offset = evmcs_field_offset(field, NULL);
++ if (offset < 0)
++ return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
+
+- /* Read the field, zero-extended to a u64 value */
+- value = vmcs12_read_any(vmcs12, field, offset);
++ /* Read the field, zero-extended to a u64 value */
++ value = evmcs_read_any(vmx->nested.hv_evmcs, field, offset);
++ }
+
+ /*
+ * Now copy part of this value to register or memory, as requested.
--- /dev/null
+From 892a42c10ddb945d3a4dcf07dccdf9cb98b21548 Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 12 Jan 2022 18:01:33 +0100
+Subject: KVM: nVMX: Implement evmcs_field_offset() suitable for handle_vmread()
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+commit 892a42c10ddb945d3a4dcf07dccdf9cb98b21548 upstream.
+
+In preparation to allowing reads from Enlightened VMCS from
+handle_vmread(), implement evmcs_field_offset() to get the correct
+read offset. get_evmcs_offset(), which is being used by KVM-on-Hyper-V,
+is almost what's needed but a few things need to be adjusted. First,
+WARN_ON() is unacceptable for handle_vmread() as any field can (in
+theory) be supplied by the guest and not all fields are defined in
+eVMCS v1. Second, we need to handle 'holes' in eVMCS (missing fields).
+It also sounds like a good idea to WARN_ON() if such fields are ever
+accessed by KVM-on-Hyper-V.
+
+Implement dedicated evmcs_field_offset() helper.
+
+No functional change intended.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Message-Id: <20220112170134.1904308-5-vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx/evmcs.c | 3 +--
+ arch/x86/kvm/vmx/evmcs.h | 32 ++++++++++++++++++++++++--------
+ 2 files changed, 25 insertions(+), 10 deletions(-)
+
+--- a/arch/x86/kvm/vmx/evmcs.c
++++ b/arch/x86/kvm/vmx/evmcs.c
+@@ -12,8 +12,6 @@
+
+ DEFINE_STATIC_KEY_FALSE(enable_evmcs);
+
+-#if IS_ENABLED(CONFIG_HYPERV)
+-
+ #define EVMCS1_OFFSET(x) offsetof(struct hv_enlightened_vmcs, x)
+ #define EVMCS1_FIELD(number, name, clean_field)[ROL16(number, 6)] = \
+ {EVMCS1_OFFSET(name), clean_field}
+@@ -296,6 +294,7 @@ const struct evmcs_field vmcs_field_to_e
+ };
+ const unsigned int nr_evmcs_1_fields = ARRAY_SIZE(vmcs_field_to_evmcs_1);
+
++#if IS_ENABLED(CONFIG_HYPERV)
+ __init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf)
+ {
+ vmcs_conf->pin_based_exec_ctrl &= ~EVMCS1_UNSUPPORTED_PINCTRL;
+--- a/arch/x86/kvm/vmx/evmcs.h
++++ b/arch/x86/kvm/vmx/evmcs.h
+@@ -63,8 +63,6 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs);
+ #define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
+ #define EVMCS1_UNSUPPORTED_VMFUNC (VMX_VMFUNC_EPTP_SWITCHING)
+
+-#if IS_ENABLED(CONFIG_HYPERV)
+-
+ struct evmcs_field {
+ u16 offset;
+ u16 clean_field;
+@@ -73,26 +71,44 @@ struct evmcs_field {
+ extern const struct evmcs_field vmcs_field_to_evmcs_1[];
+ extern const unsigned int nr_evmcs_1_fields;
+
+-static __always_inline int get_evmcs_offset(unsigned long field,
+- u16 *clean_field)
++static __always_inline int evmcs_field_offset(unsigned long field,
++ u16 *clean_field)
+ {
+ unsigned int index = ROL16(field, 6);
+ const struct evmcs_field *evmcs_field;
+
+- if (unlikely(index >= nr_evmcs_1_fields)) {
+- WARN_ONCE(1, "KVM: accessing unsupported EVMCS field %lx\n",
+- field);
++ if (unlikely(index >= nr_evmcs_1_fields))
+ return -ENOENT;
+- }
+
+ evmcs_field = &vmcs_field_to_evmcs_1[index];
+
++ /*
++ * Use offset=0 to detect holes in eVMCS. This offset belongs to
++ * 'revision_id' but this field has no encoding and is supposed to
++ * be accessed directly.
++ */
++ if (unlikely(!evmcs_field->offset))
++ return -ENOENT;
++
+ if (clean_field)
+ *clean_field = evmcs_field->clean_field;
+
+ return evmcs_field->offset;
+ }
+
++#if IS_ENABLED(CONFIG_HYPERV)
++
++static __always_inline int get_evmcs_offset(unsigned long field,
++ u16 *clean_field)
++{
++ int offset = evmcs_field_offset(field, clean_field);
++
++ WARN_ONCE(offset < 0, "KVM: accessing unsupported EVMCS field %lx\n",
++ field);
++
++ return offset;
++}
++
+ static __always_inline void evmcs_write64(unsigned long field, u64 value)
+ {
+ u16 clean_field;
--- /dev/null
+From 2423a4c0d17418eca1ba1e3f48684cb2ab7523d5 Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 12 Jan 2022 18:01:32 +0100
+Subject: KVM: nVMX: Rename vmcs_to_field_offset{,_table}
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+commit 2423a4c0d17418eca1ba1e3f48684cb2ab7523d5 upstream.
+
+vmcs_to_field_offset{,_table} may sound misleading as VMCS is an opaque
+blob which is not supposed to be accessed directly. In fact,
+vmcs_to_field_offset{,_table} are related to KVM defined VMCS12 structure.
+
+Rename vmcs_field_to_offset() to get_vmcs12_field_offset() for clarity.
+
+No functional change intended.
+
+Reviewed-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Message-Id: <20220112170134.1904308-4-vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx/nested.c | 6 +++---
+ arch/x86/kvm/vmx/vmcs12.c | 4 ++--
+ arch/x86/kvm/vmx/vmcs12.h | 6 +++---
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -5086,7 +5086,7 @@ static int handle_vmread(struct kvm_vcpu
+ /* Decode instruction info and find the field to read */
+ field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf));
+
+- offset = vmcs_field_to_offset(field);
++ offset = get_vmcs12_field_offset(field);
+ if (offset < 0)
+ return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
+
+@@ -5189,7 +5189,7 @@ static int handle_vmwrite(struct kvm_vcp
+
+ field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf));
+
+- offset = vmcs_field_to_offset(field);
++ offset = get_vmcs12_field_offset(field);
+ if (offset < 0)
+ return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
+
+@@ -6435,7 +6435,7 @@ static u64 nested_vmx_calc_vmcs_enum_msr
+ max_idx = 0;
+ for (i = 0; i < nr_vmcs12_fields; i++) {
+ /* The vmcs12 table is very, very sparsely populated. */
+- if (!vmcs_field_to_offset_table[i])
++ if (!vmcs12_field_offsets[i])
+ continue;
+
+ idx = vmcs_field_index(VMCS12_IDX_TO_ENC(i));
+--- a/arch/x86/kvm/vmx/vmcs12.c
++++ b/arch/x86/kvm/vmx/vmcs12.c
+@@ -8,7 +8,7 @@
+ FIELD(number, name), \
+ [ROL16(number##_HIGH, 6)] = VMCS12_OFFSET(name) + sizeof(u32)
+
+-const unsigned short vmcs_field_to_offset_table[] = {
++const unsigned short vmcs12_field_offsets[] = {
+ FIELD(VIRTUAL_PROCESSOR_ID, virtual_processor_id),
+ FIELD(POSTED_INTR_NV, posted_intr_nv),
+ FIELD(GUEST_ES_SELECTOR, guest_es_selector),
+@@ -151,4 +151,4 @@ const unsigned short vmcs_field_to_offse
+ FIELD(HOST_RSP, host_rsp),
+ FIELD(HOST_RIP, host_rip),
+ };
+-const unsigned int nr_vmcs12_fields = ARRAY_SIZE(vmcs_field_to_offset_table);
++const unsigned int nr_vmcs12_fields = ARRAY_SIZE(vmcs12_field_offsets);
+--- a/arch/x86/kvm/vmx/vmcs12.h
++++ b/arch/x86/kvm/vmx/vmcs12.h
+@@ -361,10 +361,10 @@ static inline void vmx_check_vmcs12_offs
+ CHECK_OFFSET(guest_pml_index, 996);
+ }
+
+-extern const unsigned short vmcs_field_to_offset_table[];
++extern const unsigned short vmcs12_field_offsets[];
+ extern const unsigned int nr_vmcs12_fields;
+
+-static inline short vmcs_field_to_offset(unsigned long field)
++static inline short get_vmcs12_field_offset(unsigned long field)
+ {
+ unsigned short offset;
+ unsigned int index;
+@@ -377,7 +377,7 @@ static inline short vmcs_field_to_offset
+ return -ENOENT;
+
+ index = array_index_nospec(index, nr_vmcs12_fields);
+- offset = vmcs_field_to_offset_table[index];
++ offset = vmcs12_field_offsets[index];
+ if (offset == 0)
+ return -ENOENT;
+ return offset;
usb-dwc3-xilinx-fix-uninitialized-return-value.patch
usr-include-makefile-add-linux-nfc.h-to-the-compile-test-coverage.patch
tools-testing-scatterlist-add-missing-defines.patch
+kvm-nvmx-rename-vmcs_to_field_offset-_table.patch
+kvm-nvmx-implement-evmcs_field_offset-suitable-for-handle_vmread.patch
+kvm-nvmx-allow-vmread-when-enlightened-vmcs-is-in-use.patch
+block-fix-wrong-offset-in-bio_truncate.patch