FAILED: patch "[PATCH] KVM: nVMX: Apply addr size mask to effective address for VMX" failed to apply to 4.4-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 8570f9e881e3fde98801bb3a47eef84dd934d405 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <[email protected]>
Date: Wed, 23 Jan 2019 14:39:24 -0800
Subject: [PATCH] KVM: nVMX: Apply addr size mask to effective address for VMX
instructions
The address size of an instruction affects the effective address, not the virtual/linear address. The final address may still be truncated, e.g. to 32-bits outside of long mode, but that happens irrespective of the address size, e.g. a 32-bit address size can yield a 64-bit virtual address when using FS/GS with a non-zero base.
arch/x86/kvm/vmx/nested.c +23 -2
@@ -4029,20 +4029,41 @@ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification,if (index_is_valid) off +=kvm_register_read (vcpu, index_reg)<<scaling;vmx_get_segment (vcpu, &s, seg_reg); - *ret = s.base + off; +/* +* The effective address, i.e. @off, of a memory operand is truncated +* based on the address size of the instruction. Note that this is +* the *effective address*, i.e. the address prior to accounting for +* the segment's base. +*/ if (addr_size ==1 )/* 32 bit */ - *ret &=0xffffffff ; + off &=0xffffffff ; +else if (addr_size ==0 )/* 16 bit */ + off &=0xffff ;/* Checks for #GP/#SS exceptions. */ exn = false;if (is_long_mode (vcpu)) { +/* +* The virtual/linear address is never truncated in 64-bit +* mode, e.g. a 32-bit address size can yield a 64-bit virtual +* address when using FS/GS with a non-zero base. +*/ + *ret = s.base + off; +/* 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! */ exn =is_noncanonical_address (*ret, vcpu); }else if (is_protmode (vcpu)) { +/* +* When not in long mode, the virtual/linear address is +* unconditionally truncated to 32 bits regardless of the +* address size. +*/ + *ret = (s.base + off) &0xffffffff ; +/* Protected mode: apply checks for segment validity in the * following order: * - segment type check (#GP(0) may be thrown)