Guests using IBRS incur a large performance penalty
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Fix Released
|
High
|
Gavin Guo | ||
Trusty |
Fix Released
|
High
|
Gavin Guo | ||
Xenial |
Fix Released
|
High
|
Gavin Guo |
Bug Description
[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.
[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.
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_
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 v3.13 kernel hasn't been tested. However, the patch can be viewed
at:
http://
The v4.4 patch:
http://
[Test]
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/
1
<Several minutes later...>
host$ cat /proc/sys/
0
host$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
111111111111110
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/
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/
guest$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
111111111111111
host$ echo 2 | sudo tee /proc/sys/
host$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
111111111111111
host$ echo 0 | sudo tee /proc/sys/
host$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
000000000000000
guest$ for i in {0..55}; do sudo rdmsr 0x48 -p $i; done
000000000000000
CVE References
Changed in linux (Ubuntu): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Xenial): | |
status: | New → Triaged |
Changed in linux (Ubuntu): | |
status: | Confirmed → Triaged |
Changed in linux (Ubuntu Xenial): | |
importance: | Undecided → Medium |
tags: | added: kernel-da-key xenial |
Changed in linux (Ubuntu Xenial): | |
assignee: | Guilherme G. Piccoli (gpiccoli) → Gavin Guo (mimi0213kimo) |
Changed in linux (Ubuntu): | |
assignee: | Guilherme G. Piccoli (gpiccoli) → Gavin Guo (mimi0213kimo) |
Changed in linux (Ubuntu Trusty): | |
status: | New → In Progress |
Changed in linux (Ubuntu Xenial): | |
status: | In Progress → Fix Committed |
tags: | added: cscc |
Changed in linux (Ubuntu Trusty): | |
status: | In Progress → Fix Released |
Changed in linux (Ubuntu): | |
status: | In Progress → Fix Released |
Changed in linux (Ubuntu Trusty): | |
importance: | Undecided → High |
assignee: | nobody → Gavin Guo (mimi0213kimo) |
This bug is missing log files that will aid in diagnosing the problem. While running an Ubuntu kernel (not a mainline or third-party kernel) please enter the following command in a terminal window:
apport-collect 1764956
and then change the status of the bug to 'Confirmed'.
If, due to the nature of the issue you have encountered, you are unable to run this command, please add a comment stating that fact and change the bug status to 'Confirmed'.
This change has been made by an automated script, maintained by the Ubuntu Kernel Team.