]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/kvm-nvmx-apply-addr-size-mask-to-effective-address-for-vmx-instructions.patch
843579c2c0f3e82ba25a24f44411770e39ec6fe0
[thirdparty/kernel/stable-queue.git] / queue-4.19 / kvm-nvmx-apply-addr-size-mask-to-effective-address-for-vmx-instructions.patch
1 From 8570f9e881e3fde98801bb3a47eef84dd934d405 Mon Sep 17 00:00:00 2001
2 From: Sean Christopherson <sean.j.christopherson@intel.com>
3 Date: Wed, 23 Jan 2019 14:39:24 -0800
4 Subject: KVM: nVMX: Apply addr size mask to effective address for VMX instructions
5
6 From: Sean Christopherson <sean.j.christopherson@intel.com>
7
8 commit 8570f9e881e3fde98801bb3a47eef84dd934d405 upstream.
9
10 The address size of an instruction affects the effective address, not
11 the virtual/linear address. The final address may still be truncated,
12 e.g. to 32-bits outside of long mode, but that happens irrespective of
13 the address size, e.g. a 32-bit address size can yield a 64-bit virtual
14 address when using FS/GS with a non-zero base.
15
16 Fixes: 064aea774768 ("KVM: nVMX: Decoding memory operands of VMX instructions")
17 Cc: stable@vger.kernel.org
18 Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
19 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
20 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21
22 ---
23 arch/x86/kvm/vmx.c | 25 +++++++++++++++++++++++--
24 1 file changed, 23 insertions(+), 2 deletions(-)
25
26 --- a/arch/x86/kvm/vmx.c
27 +++ b/arch/x86/kvm/vmx.c
28 @@ -8193,20 +8193,41 @@ static int get_vmx_mem_address(struct kv
29 if (index_is_valid)
30 off += kvm_register_read(vcpu, index_reg)<<scaling;
31 vmx_get_segment(vcpu, &s, seg_reg);
32 - *ret = s.base + off;
33
34 + /*
35 + * The effective address, i.e. @off, of a memory operand is truncated
36 + * based on the address size of the instruction. Note that this is
37 + * the *effective address*, i.e. the address prior to accounting for
38 + * the segment's base.
39 + */
40 if (addr_size == 1) /* 32 bit */
41 - *ret &= 0xffffffff;
42 + off &= 0xffffffff;
43 + else if (addr_size == 0) /* 16 bit */
44 + off &= 0xffff;
45
46 /* Checks for #GP/#SS exceptions. */
47 exn = false;
48 if (is_long_mode(vcpu)) {
49 + /*
50 + * The virtual/linear address is never truncated in 64-bit
51 + * mode, e.g. a 32-bit address size can yield a 64-bit virtual
52 + * address when using FS/GS with a non-zero base.
53 + */
54 + *ret = s.base + off;
55 +
56 /* Long mode: #GP(0)/#SS(0) if the memory address is in a
57 * non-canonical form. This is the only check on the memory
58 * destination for long mode!
59 */
60 exn = is_noncanonical_address(*ret, vcpu);
61 } else if (is_protmode(vcpu)) {
62 + /*
63 + * When not in long mode, the virtual/linear address is
64 + * unconditionally truncated to 32 bits regardless of the
65 + * address size.
66 + */
67 + *ret = (s.base + off) & 0xffffffff;
68 +
69 /* Protected mode: apply checks for segment validity in the
70 * following order:
71 * - segment type check (#GP(0) may be thrown)