Patches 1 and 2 fix two cases where a guest could hang at 100% CPU
due to mis-emulation of a failing invept or invvpid.
Patch 3 works around a bug in RHEL6 KVM, which is exposed by nested
VPID support; RHEL6 KVM uses single-context invvpid unconditionally,
but until now KVM did not provide it.
Paolo
Paolo Bonzini (3):
KVM: VMX: avoid guest hang on invalid invept instruction
KVM: VMX: avoid guest hang on invalid invvpid instruction
KVM: VMX: fix nested vpid for old KVM guests
arch/x86/kvm/vmx.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
--
1.8.3.1
A guest executing an invalid invept instruction would hang
because the instruction pointer was not updated.
Cc: [email protected]
Fixes: bfd0a56b90005f8c8a004baf407ad90045c2b11e
Signed-off-by: Paolo Bonzini <[email protected]>
---
arch/x86/kvm/vmx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 5e45c2731a5d..17b20b52d30e 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -7399,6 +7399,7 @@ static int handle_invept(struct kvm_vcpu *vcpu)
if (!(types & (1UL << type))) {
nested_vmx_failValid(vcpu,
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+ skip_emulated_instruction(vcpu);
return 1;
}
--
1.8.3.1
Old KVM guests invoke single-context invvpid without actually checking
whether it is supported. This was fixed by commit 518c8ae ("KVM: VMX:
Make sure single type invvpid is supported before issuing invvpid
instruction", 2010-08-01) and the patch after, but pre-2.6.36
kernels lack it including RHEL 6.
Reported-by: [email protected]
Cc: [email protected]
Fixes: 99b83ac893b84ed1a62ad6d1f2b6cc32026b9e85
Signed-off-by: Paolo Bonzini <[email protected]>
---
arch/x86/kvm/vmx.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 728f31bd350e..5cf66c14aac0 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2712,8 +2712,15 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
} else
vmx->nested.nested_vmx_ept_caps = 0;
+ /*
+ * Old versions of KVM use the single-context version without
+ * checking for support, so declare that it is supported even
+ * though it is treated as global context. The alternative is
+ * not failing the single-context invvpid, and it is worse.
+ */
if (enable_vpid)
vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
+ VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT |
VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
else
vmx->nested.nested_vmx_vpid_caps = 0;
@@ -7475,12 +7482,17 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
}
switch (type) {
+ case VMX_VPID_EXTENT_SINGLE_CONTEXT:
+ /*
+ * Old versions of KVM use the single-context version so we
+ * have to support it; just treat it the same as all-context.
+ */
case VMX_VPID_EXTENT_ALL_CONTEXT:
__vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
nested_vmx_succeed(vcpu);
break;
default:
- /* Trap single context invalidation invvpid calls */
+ /* Trap individual address invalidation invvpid calls */
BUG_ON(1);
break;
}
--
1.8.3.1
A guest executing an invalid invvpid instruction would hang
because the instruction pointer was not updated.
Reported-by: [email protected]
Cc: [email protected]
Fixes: 99b83ac893b84ed1a62ad6d1f2b6cc32026b9e85
Signed-off-by: Paolo Bonzini <[email protected]>
---
arch/x86/kvm/vmx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 17b20b52d30e..728f31bd350e 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -7458,6 +7458,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
if (!(types & (1UL << type))) {
nested_vmx_failValid(vcpu,
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+ skip_emulated_instruction(vcpu);
return 1;
}
--
1.8.3.1
On Fri, Mar 18, 2016 at 9:09 AM, Paolo Bonzini <[email protected]> wrote:
> Patches 1 and 2 fix two cases where a guest could hang at 100% CPU
> due to mis-emulation of a failing invept or invvpid.
Will you be sending out kvm-unit-test test cases for these?
>
> Patch 3 works around a bug in RHEL6 KVM, which is exposed by nested
> VPID support; RHEL6 KVM uses single-context invvpid unconditionally,
> but until now KVM did not provide it.
>
> Paolo
>
For the series,
Reviewed-by: David Matlack <[email protected]>
> Paolo Bonzini (3):
> KVM: VMX: avoid guest hang on invalid invept instruction
> KVM: VMX: avoid guest hang on invalid invvpid instruction
> KVM: VMX: fix nested vpid for old KVM guests
>
> arch/x86/kvm/vmx.c | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> --
> 1.8.3.1
>
On 18/03/2016 18:42, David Matlack wrote:
> On Fri, Mar 18, 2016 at 9:09 AM, Paolo Bonzini <[email protected]> wrote:
>> Patches 1 and 2 fix two cases where a guest could hang at 100% CPU
>> due to mis-emulation of a failing invept or invvpid.
>
> Will you be sending out kvm-unit-test test cases for these?
Yes, of course, especially for patches 1 and 2. However I first want to
add a --enable-unsafe option for stuff that breaks particularly badly
when the test fails. We don't do nested virt CVEs (yet), but all of
these would be treated as vulnerabilities if we did---the tests would
effectively DoS the host.
The infamous #AC failure could also be under a flag like that, and I
remember a similar topic popping up with a LAPIC fix from Google.
Paolo
>>
>> Patch 3 works around a bug in RHEL6 KVM, which is exposed by nested
>> VPID support; RHEL6 KVM uses single-context invvpid unconditionally,
>> but until now KVM did not provide it.
>>
>> Paolo
>>
>
> For the series,
>
> Reviewed-by: David Matlack <[email protected]>
>
>> Paolo Bonzini (3):
>> KVM: VMX: avoid guest hang on invalid invept instruction
>> KVM: VMX: avoid guest hang on invalid invvpid instruction
>> KVM: VMX: fix nested vpid for old KVM guests
>>
>> arch/x86/kvm/vmx.c | 16 +++++++++++++++-
>> 1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> --
>> 1.8.3.1
>>
On Fri, Mar 18, 2016 at 10:58 AM, Paolo Bonzini <[email protected]> wrote:
>
>
> On 18/03/2016 18:42, David Matlack wrote:
>> On Fri, Mar 18, 2016 at 9:09 AM, Paolo Bonzini <[email protected]> wrote:
>>> Patches 1 and 2 fix two cases where a guest could hang at 100% CPU
>>> due to mis-emulation of a failing invept or invvpid.
>>
>> Will you be sending out kvm-unit-test test cases for these?
>
> Yes, of course, especially for patches 1 and 2.
Thanks!
> However I first want to
> add a --enable-unsafe option for stuff that breaks particularly badly
> when the test fails. We don't do nested virt CVEs (yet), but all of
> these would be treated as vulnerabilities if we did---the tests would
> effectively DoS the host.
How does this DoS the host? The guest is stuck executing the same
instruction over and over, but it's exiting to KVM every time,
allowing KVM to reschedule the VCPU. I would agree it DoSes the guest.
>
> The infamous #AC failure could also be under a flag like that, and I
> remember a similar topic popping up with a LAPIC fix from Google.
>
> Paolo
>
>>>
>>> Patch 3 works around a bug in RHEL6 KVM, which is exposed by nested
>>> VPID support; RHEL6 KVM uses single-context invvpid unconditionally,
>>> but until now KVM did not provide it.
>>>
>>> Paolo
>>>
>>
>> For the series,
>>
>> Reviewed-by: David Matlack <[email protected]>
>>
>>> Paolo Bonzini (3):
>>> KVM: VMX: avoid guest hang on invalid invept instruction
>>> KVM: VMX: avoid guest hang on invalid invvpid instruction
>>> KVM: VMX: fix nested vpid for old KVM guests
>>>
>>> arch/x86/kvm/vmx.c | 16 +++++++++++++++-
>>> 1 file changed, 15 insertions(+), 1 deletion(-)
>>>
>>> --
>>> 1.8.3.1
>>>
On 18/03/2016 19:04, David Matlack wrote:
> > the tests would effectively DoS the host.
>
> How does this DoS the host? The guest is stuck executing the same
> instruction over and over, but it's exiting to KVM every time,
> allowing KVM to reschedule the VCPU. I would agree it DoSes the guest.
You're right, these tests are safe.
Paolo