Vincent, I'll update the description to match the SRU requirements, but
your original description will still be available.

** Description changed:

- Hello!
+ [Impact]
+ the IBRS would be mistakenly enabled in the host when the switching
+ from an IBRS-enabled VM and that causes the performance overhead in
+ the host. The other condition could also mistakenly disables the IBRS
+ in VM when context-switching from the host. And this could be
+ considered a CVE host.
  
- As of Linux 4.4.0-119, when a KVM guest is using IBRS, this incurs a
- very large performance penalty on the hosts and other guests.
+ [Fix]
+ The patch fixes the logic inside the x86_virt_spec_ctrl that it checks
+ the ibrs_enabled and _or_ the hostval with the SPEC_CTRL_IBRS as the
+ x86_spec_ctrl_base by default is zero. Because the upstream
+ implementation is not equal to the Xenial's implementation. Upstream
+ doesn't use the IBRS as the formal fix. So, by default, it's zero.
  
- From my understanding, the patch
- f676aa34b4027d1a7a4bbcc58b81b20c68c7ce0c is incomplete. If host doesn't
- handle IBRS itself (which is now the case by default since 4.4.0-116: it
- relies on retpoline instead) but the guest does (eg running an earlier
- kernel), the guest will set IBRS for the CPU it is running on from time
- to time but if it gets preempted at some point, the IBRS bit will stay,
- incurring a major performance penalty for all other users of the CPU
- (host userland, host kernel and other guests not caring about IBRS). The
- equivalent patch in mainline (d28b387fb74da95d69d2615732f50cceb38e9a4d)
- ensure the appropriate MSR is correctly restored when switching from one
- guest to another or from one guest to host.
+ On the other hand, after the VM exit, the SPEC_CTRL register also
+ needs to be saved manually by reading the SPEC_CTRL MSR as the MSR
+ intercept is disabled by default in the hardware_setup(v4.4) and
+ vmx_init(v3.13). The access to SPEC_CTRL MSR in VM is direct and
+ doesn't trigger a trap. So, the vmx_set_msr() function isn't called.
  
- The issue is easy to reproduce: host running 4.4.0-119, exposing
- "spec_ctrl" to a guest running CentOS 7.4 with its January kernel. Wait
- a few minutes and the host will become pretty slow. A simple shell loop
- will take 10 more times to execute. Executing "sysctl -w
- kernel.ibrs_dump=1" will show that most real cores have now their IBRS
- bit set to 1.
+ The v3.13 kernel hasn't been tested. However, the patch can be viewed
+ at:
+ 
http://kernel.ubuntu.com/git/gavinguo/ubuntu-trusty-amd64.git/log/?h=sf00191076-sru
  
- A workaround is to reeanble IBRS on the host (sysctl -w
- kernel.ibrs_enabled=1). This way, IBRS will be correctly disabled when
- changing context.
+ The v4.4 patch:
+ 
http://kernel.ubuntu.com/git/gavinguo/ubuntu-xenial.git/log/?h=sf00191076-spectre-v2-regres-backport-juerg
  
- A long term solution would be to properly backport the patch from
- mainline. It is not part of the 4.4 stable branch and it seems not
- trivial to port.
+ [Test]
  
- A mid term solution could be to remove the faulty patch (not exposing
- IBRS), since most VM don't need it anymore. This also salvage the
- ability to use IBPB (which doesn't seem to alter performance that much)
- but it isn't believed to be essential.
+ The patch has been tested on the 4.4.0-140.166 and works fine.
+ 
+ The reproducing environment:
+ Guest kernel version: 4.4.0-138.164
+ Host kernel version: 4.4.0-140.166
+ 
+ (host IBRS, guest IBRS)
+ 
+ - 1). (0, 1).
+ The case can be reproduced by the following instructions:
+ guest$ echo 1 | sudo tee /proc/sys/kernel/ibrs_enabled
+ 1
+ 
+ <Several minutes later...>
+ 
+ host$ cat /proc/sys/kernel/ibrs_enabled
+ 0
+ host$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
+ 11111111111111000000000000000000010010100000000000000000
+ 
+ Some of the IBRS bit inside the SPEC_CTRL MSR are mistakenly
+ enabled.
+ 
+ host$ taskset -c 5 stress-ng -c 1 --cpu-ops 2500
+ stress-ng: info:  [11264] defaulting to a 86400 second run per stressor
+ stress-ng: info:  [11264] dispatching hogs: 1 cpu
+ stress-ng: info:  [11264] cache allocate: default cache size: 35840K
+ stress-ng: info:  [11264] successful run completed in 33.48s
+ 
+ The host kernel didn't notice the IBRS bit is enabled. So, the situation
+ is the same as "echo 2 > /proc/sys/kernel/ibrs_enabled" in the host.
+ And running the stress-ng is a pure userspace CPU capability
+ calculation. So, the performance downgrades to about 1/3. Without the
+ IBRS enabled, it needs about 10s.
+ 
+ - 2). (1, 1) disables IBRS in host -> (0, 1) actually it becomes (0, 0).
+ The guest IBRS has been mistakenly disabled.
+ 
+ guest$ echo 2 | sudo tee /proc/sys/kernel/ibrs_enabled
+ guest$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
+ 11111111111111111111111111111111111111111111111111111111
+ 
+ host$ echo 2 | sudo tee /proc/sys/kernel/ibrs_enabled
+ host$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
+ 11111111111111111111111111111111111111111111111111111111
+ host$ echo 0 | sudo tee /proc/sys/kernel/ibrs_enabled
+ host$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
+ 00000000000000000000000000000000000000000000000000000000
+ 
+ guest$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
+ 00000000000000000000000000000000000000000000000000000000

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1764956

Title:
  Guests using IBRS incur a large performance penalty

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1764956/+subscriptions

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to