]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 May 2020 11:46:38 +0000 (13:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 May 2020 11:46:38 +0000 (13:46 +0200)
added patches:
kvm-vmx-explicitly-reference-rcx-as-the-vmx_vcpu-pointer-in-asm-blobs.patch
kvm-vmx-mark-rcx-rdx-and-rsi-as-clobbered-in-vmx_vcpu_run-s-asm-blob.patch

queue-4.19/kvm-vmx-explicitly-reference-rcx-as-the-vmx_vcpu-pointer-in-asm-blobs.patch [new file with mode: 0644]
queue-4.19/kvm-vmx-mark-rcx-rdx-and-rsi-as-clobbered-in-vmx_vcpu_run-s-asm-blob.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/kvm-vmx-explicitly-reference-rcx-as-the-vmx_vcpu-pointer-in-asm-blobs.patch b/queue-4.19/kvm-vmx-explicitly-reference-rcx-as-the-vmx_vcpu-pointer-in-asm-blobs.patch
new file mode 100644 (file)
index 0000000..ab09a2c
--- /dev/null
@@ -0,0 +1,154 @@
+From 051a2d3e59e51ae49fd56aef34e472832897ce46 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+Date: Thu, 20 Dec 2018 12:25:16 -0800
+Subject: KVM: VMX: Explicitly reference RCX as the vmx_vcpu pointer in asm blobs
+
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+
+commit 051a2d3e59e51ae49fd56aef34e472832897ce46 upstream.
+
+Use '%% " _ASM_CX"' instead of '%0' to dereference RCX, i.e. the
+'struct vcpu_vmx' pointer, in the VM-Enter asm blobs of vmx_vcpu_run()
+and nested_vmx_check_vmentry_hw().  Using the symbolic name means that
+adding/removing an output parameter(s) requires "rewriting" almost all
+of the asm blob, which makes it nearly impossible to understand what's
+being changed in even the most minor patches.
+
+Opportunistically improve the code comments.
+
+Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
+Reviewed-by: Andi Kleen <ak@linux.intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/vmx.c |   86 ++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 47 insertions(+), 39 deletions(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -10776,9 +10776,9 @@ static void __noclone vmx_vcpu_run(struc
+               "push %%" _ASM_DX "; push %%" _ASM_BP ";"
+               "push %%" _ASM_CX " \n\t" /* placeholder for guest rcx */
+               "push %%" _ASM_CX " \n\t"
+-              "cmp %%" _ASM_SP ", %c[host_rsp](%0) \n\t"
++              "cmp %%" _ASM_SP ", %c[host_rsp](%%" _ASM_CX ") \n\t"
+               "je 1f \n\t"
+-              "mov %%" _ASM_SP ", %c[host_rsp](%0) \n\t"
++              "mov %%" _ASM_SP ", %c[host_rsp](%%" _ASM_CX ") \n\t"
+               /* Avoid VMWRITE when Enlightened VMCS is in use */
+               "test %%" _ASM_SI ", %%" _ASM_SI " \n\t"
+               "jz 2f \n\t"
+@@ -10788,32 +10788,33 @@ static void __noclone vmx_vcpu_run(struc
+               __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
+               "1: \n\t"
+               /* Reload cr2 if changed */
+-              "mov %c[cr2](%0), %%" _ASM_AX " \n\t"
++              "mov %c[cr2](%%" _ASM_CX "), %%" _ASM_AX " \n\t"
+               "mov %%cr2, %%" _ASM_DX " \n\t"
+               "cmp %%" _ASM_AX ", %%" _ASM_DX " \n\t"
+               "je 3f \n\t"
+               "mov %%" _ASM_AX", %%cr2 \n\t"
+               "3: \n\t"
+               /* Check if vmlaunch of vmresume is needed */
+-              "cmpb $0, %c[launched](%0) \n\t"
++              "cmpb $0, %c[launched](%%" _ASM_CX ") \n\t"
+               /* Load guest registers.  Don't clobber flags. */
+-              "mov %c[rax](%0), %%" _ASM_AX " \n\t"
+-              "mov %c[rbx](%0), %%" _ASM_BX " \n\t"
+-              "mov %c[rdx](%0), %%" _ASM_DX " \n\t"
+-              "mov %c[rsi](%0), %%" _ASM_SI " \n\t"
+-              "mov %c[rdi](%0), %%" _ASM_DI " \n\t"
+-              "mov %c[rbp](%0), %%" _ASM_BP " \n\t"
++              "mov %c[rax](%%" _ASM_CX "), %%" _ASM_AX " \n\t"
++              "mov %c[rbx](%%" _ASM_CX "), %%" _ASM_BX " \n\t"
++              "mov %c[rdx](%%" _ASM_CX "), %%" _ASM_DX " \n\t"
++              "mov %c[rsi](%%" _ASM_CX "), %%" _ASM_SI " \n\t"
++              "mov %c[rdi](%%" _ASM_CX "), %%" _ASM_DI " \n\t"
++              "mov %c[rbp](%%" _ASM_CX "), %%" _ASM_BP " \n\t"
+ #ifdef CONFIG_X86_64
+-              "mov %c[r8](%0),  %%r8  \n\t"
+-              "mov %c[r9](%0),  %%r9  \n\t"
+-              "mov %c[r10](%0), %%r10 \n\t"
+-              "mov %c[r11](%0), %%r11 \n\t"
+-              "mov %c[r12](%0), %%r12 \n\t"
+-              "mov %c[r13](%0), %%r13 \n\t"
+-              "mov %c[r14](%0), %%r14 \n\t"
+-              "mov %c[r15](%0), %%r15 \n\t"
++              "mov %c[r8](%%" _ASM_CX "),  %%r8  \n\t"
++              "mov %c[r9](%%" _ASM_CX "),  %%r9  \n\t"
++              "mov %c[r10](%%" _ASM_CX "), %%r10 \n\t"
++              "mov %c[r11](%%" _ASM_CX "), %%r11 \n\t"
++              "mov %c[r12](%%" _ASM_CX "), %%r12 \n\t"
++              "mov %c[r13](%%" _ASM_CX "), %%r13 \n\t"
++              "mov %c[r14](%%" _ASM_CX "), %%r14 \n\t"
++              "mov %c[r15](%%" _ASM_CX "), %%r15 \n\t"
+ #endif
+-              "mov %c[rcx](%0), %%" _ASM_CX " \n\t" /* kills %0 (ecx) */
++              /* Load guest RCX.  This kills the vmx_vcpu pointer! */
++              "mov %c[rcx](%%" _ASM_CX "), %%" _ASM_CX " \n\t"
+               /* Enter guest mode */
+               "jne 1f \n\t"
+@@ -10821,26 +10822,33 @@ static void __noclone vmx_vcpu_run(struc
+               "jmp 2f \n\t"
+               "1: " __ex(ASM_VMX_VMRESUME) "\n\t"
+               "2: "
+-              /* Save guest registers, load host registers, keep flags */
+-              "mov %0, %c[wordsize](%%" _ASM_SP ") \n\t"
+-              "pop %0 \n\t"
+-              "setbe %c[fail](%0)\n\t"
+-              "mov %%" _ASM_AX ", %c[rax](%0) \n\t"
+-              "mov %%" _ASM_BX ", %c[rbx](%0) \n\t"
+-              __ASM_SIZE(pop) " %c[rcx](%0) \n\t"
+-              "mov %%" _ASM_DX ", %c[rdx](%0) \n\t"
+-              "mov %%" _ASM_SI ", %c[rsi](%0) \n\t"
+-              "mov %%" _ASM_DI ", %c[rdi](%0) \n\t"
+-              "mov %%" _ASM_BP ", %c[rbp](%0) \n\t"
++
++              /* Save guest's RCX to the stack placeholder (see above) */
++              "mov %%" _ASM_CX ", %c[wordsize](%%" _ASM_SP ") \n\t"
++
++              /* Load host's RCX, i.e. the vmx_vcpu pointer */
++              "pop %%" _ASM_CX " \n\t"
++
++              /* Set vmx->fail based on EFLAGS.{CF,ZF} */
++              "setbe %c[fail](%%" _ASM_CX ")\n\t"
++
++              /* Save all guest registers, including RCX from the stack */
++              "mov %%" _ASM_AX ", %c[rax](%%" _ASM_CX ") \n\t"
++              "mov %%" _ASM_BX ", %c[rbx](%%" _ASM_CX ") \n\t"
++              __ASM_SIZE(pop) " %c[rcx](%%" _ASM_CX ") \n\t"
++              "mov %%" _ASM_DX ", %c[rdx](%%" _ASM_CX ") \n\t"
++              "mov %%" _ASM_SI ", %c[rsi](%%" _ASM_CX ") \n\t"
++              "mov %%" _ASM_DI ", %c[rdi](%%" _ASM_CX ") \n\t"
++              "mov %%" _ASM_BP ", %c[rbp](%%" _ASM_CX ") \n\t"
+ #ifdef CONFIG_X86_64
+-              "mov %%r8,  %c[r8](%0) \n\t"
+-              "mov %%r9,  %c[r9](%0) \n\t"
+-              "mov %%r10, %c[r10](%0) \n\t"
+-              "mov %%r11, %c[r11](%0) \n\t"
+-              "mov %%r12, %c[r12](%0) \n\t"
+-              "mov %%r13, %c[r13](%0) \n\t"
+-              "mov %%r14, %c[r14](%0) \n\t"
+-              "mov %%r15, %c[r15](%0) \n\t"
++              "mov %%r8,  %c[r8](%%" _ASM_CX ") \n\t"
++              "mov %%r9,  %c[r9](%%" _ASM_CX ") \n\t"
++              "mov %%r10, %c[r10](%%" _ASM_CX ") \n\t"
++              "mov %%r11, %c[r11](%%" _ASM_CX ") \n\t"
++              "mov %%r12, %c[r12](%%" _ASM_CX ") \n\t"
++              "mov %%r13, %c[r13](%%" _ASM_CX ") \n\t"
++              "mov %%r14, %c[r14](%%" _ASM_CX ") \n\t"
++              "mov %%r15, %c[r15](%%" _ASM_CX ") \n\t"
+               /*
+                * Clear all general purpose registers (except RSP, which is loaded by
+@@ -10860,7 +10868,7 @@ static void __noclone vmx_vcpu_run(struc
+               "xor %%r15d, %%r15d \n\t"
+ #endif
+               "mov %%cr2, %%" _ASM_AX "   \n\t"
+-              "mov %%" _ASM_AX ", %c[cr2](%0) \n\t"
++              "mov %%" _ASM_AX ", %c[cr2](%%" _ASM_CX ") \n\t"
+               "xor %%eax, %%eax \n\t"
+               "xor %%ebx, %%ebx \n\t"
diff --git a/queue-4.19/kvm-vmx-mark-rcx-rdx-and-rsi-as-clobbered-in-vmx_vcpu_run-s-asm-blob.patch b/queue-4.19/kvm-vmx-mark-rcx-rdx-and-rsi-as-clobbered-in-vmx_vcpu_run-s-asm-blob.patch
new file mode 100644 (file)
index 0000000..5c9bbc9
--- /dev/null
@@ -0,0 +1,79 @@
+From sean.j.christopherson@intel.com  Tue May 12 13:42:55 2020
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+Date: Mon, 11 May 2020 17:28:15 -0700
+Subject: KVM: VMX: Mark RCX, RDX and RSI as clobbered in vmx_vcpu_run()'s asm blob
+To: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Ben Hutchings <ben.hutchings@codethink.co.uk>, Sasha Levin <sashal@kernel.org>
+Cc: Paolo Bonzini <pbonzini@redhat.com>, linux-kernel@vger.kernel.org, Tobias Urdin <tobias.urdin@binero.com>
+Message-ID: <20200512002815.2708-3-sean.j.christopherson@intel.com>
+
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+
+Based on upstream commit f3689e3f17f064fd4cd5f0cb01ae2395c94f39d9.
+
+Save RCX, RDX and RSI to fake outputs to coerce the compiler into
+treating them as clobbered.  RCX in particular is likely to be reused by
+the compiler to dereference the 'struct vcpu_vmx' pointer, which will
+result in a null pointer dereference now that RCX is zeroed by the asm
+blob.
+
+Tag the asm() blob as volatile to prevent GCC from dropping the blob,
+which is possible now that the blob has output values, all of which are
+unused.
+
+Upstream commit f3689e3f17f06 ("KVM: VMX: Save RSI to an unused output
+in the vCPU-run asm blob") is not a direct equivalent of this patch. As
+its shortlog states, it only tagged RSI as clobbered, whereas here RCX
+and RDX are also clobbered.
+
+In upstream at the time of the offending commit (b4be98039a92 in 4.19,
+0e0ab73c9a024 upstream), the inline asm blob had previously been moved
+to a dedicated helper, __vmx_vcpu_run().  For unrelated reasons,
+__vmx_vcpu_run() was put into its own optimization unit, which for all
+intents and purposes made it impossible to consume clobbered registers
+because RCX, RDX and RSI are volatile and __vmx_vcpu_run() couldn't
+itself be inlined.  In other words, the bug existed but couldn't be hit.
+
+Similarly, the lack of "volatile" was also a bug in upstream that was
+hidden by an unrelated change that exists in upstream but not in 4.19.
+In this case, the asm blob also uses ASM_CALL_CONSTRAINT (marks RSP as
+being an input/output constraint) in upstream to play nice with objtool
+due the blob making a CALL.  In 4.19, there is no CALL and thus no
+ASM_CALL_CONSTRAINT.
+
+Furthermore, both of the lurking bugs were blasted away in upstream by
+commits 5e0781df1899 ("KVM: VMX: Move vCPU-run code to a proper assembly
+routine") and fc2ba5a27a1a ("KVM: VMX: Call vCPU-run asm sub-routine
+from C and remove clobbering"), i.e. these bugs will never be directly
+fixed in upstream.
+
+Reported-by: Tobias Urdin <tobias.urdin@binero.com>
+Fixes: b4be98039a92 ("KVM: VMX: Zero out *all* general purpose registers after VM-Exit")
+Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/vmx.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -10771,7 +10771,7 @@ static void __noclone vmx_vcpu_run(struc
+       else if (static_branch_unlikely(&mds_user_clear))
+               mds_clear_cpu_buffers();
+-      asm(
++      asm volatile (
+               /* Store host registers */
+               "push %%" _ASM_DX "; push %%" _ASM_BP ";"
+               "push %%" _ASM_CX " \n\t" /* placeholder for guest rcx */
+@@ -10882,7 +10882,8 @@ static void __noclone vmx_vcpu_run(struc
+               ".global vmx_return \n\t"
+               "vmx_return: " _ASM_PTR " 2b \n\t"
+               ".popsection"
+-            : : "c"(vmx), "d"((unsigned long)HOST_RSP), "S"(evmcs_rsp),
++            : "=c"((int){0}), "=d"((int){0}), "=S"((int){0})
++            : "c"(vmx), "d"((unsigned long)HOST_RSP), "S"(evmcs_rsp),
+               [launched]"i"(offsetof(struct vcpu_vmx, __launched)),
+               [fail]"i"(offsetof(struct vcpu_vmx, fail)),
+               [host_rsp]"i"(offsetof(struct vcpu_vmx, host_rsp)),
index 213f2bad32f0b65814917f7d3eb40422eb06658c..1dd8975120e797d6ab0d66a11172d558e8e561e7 100644 (file)
@@ -28,3 +28,5 @@ arm64-hugetlb-avoid-potential-null-dereference.patch
 mm-page_alloc-fix-watchdog-soft-lockups-during-set_zone_contiguous.patch
 staging-gasket-check-the-return-value-of-gasket_get_bar_index.patch
 coredump-fix-crash-when-umh-is-disabled.patch
+kvm-vmx-explicitly-reference-rcx-as-the-vmx_vcpu-pointer-in-asm-blobs.patch
+kvm-vmx-mark-rcx-rdx-and-rsi-as-clobbered-in-vmx_vcpu_run-s-asm-blob.patch